RichTextEditorBeta
Beta. This component is new and still being tested: expect rough edges, and its props and the HTML it produces may change before it is declared stable. Please report anything odd.
A WYSIWYG editor with no dependencies: a formatting toolbar over an editable area. Bold, italic, underline, strike, inline code, headings, bulleted and numbered lists, quotes, code blocks, alignment, text color and highlight, links, images, tables, rules, clear formatting, undo and redo. Keyboard: Ctrl / Cmd + B, I, U, K (link), Z, Y.
value and onChange carry the content (or defaultValue for an uncontrolled editor); empty content is an empty string. The HTML is always sanitized, on the way in, on paste and on the way out: only a fixed set of tags, links and styles survives, so a script, an event handler or a javascript: address can never get in or out. Text pasted from other pages is cleaned the same way.
Edits are sanitized: scripts and unsafe links never get in.
<h2>Gru plans</h2><p>Select some text and use the toolbar: <strong>bold</strong>, <em>italic</em>, <a href="https://example.com">links</a>, lists, quotes, tables and more.</p><ul><li>Buy bananas</li><li>Build the freeze ray</li><li>Steal the moon</li></ul>Markdown. format="markdown" makes value Markdown instead of HTML, using the same parser as Markdown. Markdown has no underline, colors or alignment, so those buttons are left out, and code blocks do not keep a language. Switching format shows the same content in the new format.
## Banana report - **Faster** peeling - A new *golden* peel Read more in the [docs](https://example.com).Rendered
Toolbar and more. toolbar lists the buttons you want ('|' is a divider), or false for none; the names are undo, redo, block, bold, italic, underline, strike, code, color, highlight, link, unlink, image, ul, ol, quote, codeblock, hr, table, left, center, right, justify, fullscreen and clear. The fullscreen button (last in the default toolbar) makes the editor fill the window: fullScreen, defaultFullScreen and onFullScreenChange control it, the page behind does not scroll, and Escape leaves it. label, helperText and error work as on TextArea; minHeight and maxHeight size the writing area; readOnly shows the content without the toolbar. Resizing. Click an image to select it: drag the corner handle, or use the buttons for 25%, 50%, 100% or its original size (and Remove, or the Delete key). Drag the right border of a table cell to change that column's width. Sizes are saved as plain width attributes in the HTML, so they travel with the content; Markdown has no way to say them, so the Markdown format drops them. The image picker always has an Upload button (and images can be pasted): with onImageUpload the file goes to your server and you resolve with its address; without it the image is embedded in the content as a data: address, up to maxInlineImageSize (2 MB), which is handy for a demo but makes the value large. name adds a hidden input so the value travels in a native form. The pure helpers are exported too: sanitizeHtml, markdownToHtml and htmlToMarkdown.
Props
valuestringThe content (controlled): HTML, or Markdown with
format="markdown".defaultValuestringDefault:''The initial content when uncontrolled.
onChange(value: string) => voidCalled with the new content as it is edited. Empty content is an empty string.
format'html' | 'markdown'Default:'html'What
valueholds. Markdown has no underline, colors or alignment.toolbarToolbarItem[] | falseDefault:all of themThe buttons, in order (a
'|'entry is a divider), orfalsefor none.placeholderstringShown while the editor is empty.
labelReactNodeLabel above the editor.
errorReactNodeError message below the editor; sets the invalid style.
helperTextReactNodeHint below the editor while there is no
error.minHeightnumber | stringDefault:'12rem'Minimum height of the writing area. A number is px.
maxHeightnumber | stringMaximum height of the writing area; it scrolls beyond it.
disabledbooleanDefault:falseDim the editor and block editing.
readOnlybooleanDefault:falseShow the content without the toolbar and without editing.
fullScreenbooleanFill the whole window (controlled). The page behind does not scroll and Escape leaves it.
defaultFullScreenbooleanDefault:falseStart full screen when
fullScreenis not set.onFullScreenChange(fullScreen: boolean) => voidCalled when the full screen button or Escape switches it.
onImageUpload(file: File) => Promise<string>Called with an image file chosen with Upload or pasted; resolve with its address. Without it the image is embedded as a
data:address.maxInlineImageSizenumberDefault:2000000Largest image, in bytes, that is embedded when there is no
onImageUpload.namestringName for a hidden input that carries the value in a native
<form>.classNamestringDefault:''Extra classes for the root element.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | – | The content (controlled): HTML, or Markdown with format="markdown". |
defaultValue | string | '' | The initial content when uncontrolled. |
onChange | (value: string) => void | – | Called with the new content as it is edited. Empty content is an empty string. |
format | 'html' | 'markdown' | 'html' | What value holds. Markdown has no underline, colors or alignment. |
toolbar | ToolbarItem[] | false | all of them | The buttons, in order (a '|' entry is a divider), or false for none. |
placeholder | string | – | Shown while the editor is empty. |
label | ReactNode | – | Label above the editor. |
error | ReactNode | – | Error message below the editor; sets the invalid style. |
helperText | ReactNode | – | Hint below the editor while there is no error. |
minHeight | number | string | '12rem' | Minimum height of the writing area. A number is px. |
maxHeight | number | string | – | Maximum height of the writing area; it scrolls beyond it. |
disabled | boolean | false | Dim the editor and block editing. |
readOnly | boolean | false | Show the content without the toolbar and without editing. |
fullScreen | boolean | – | Fill the whole window (controlled). The page behind does not scroll and Escape leaves it. |
defaultFullScreen | boolean | false | Start full screen when fullScreen is not set. |
onFullScreenChange | (fullScreen: boolean) => void | – | Called when the full screen button or Escape switches it. |
onImageUpload | (file: File) => Promise<string> | – | Called with an image file chosen with Upload or pasted; resolve with its address. Without it the image is embedded as a data: address. |
maxInlineImageSize | number | 2000000 | Largest image, in bytes, that is embedded when there is no onImageUpload. |
name | string | – | Name for a hidden input that carries the value in a native <form>. |
className | string | '' | Extra classes for the root element. |