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.

Plans

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.

Editor
Markdown
## Banana report

- **Faster** peeling
- A new *golden* peel

Read more in the [docs](https://example.com).
Rendered

Banana report

  • Faster peeling
  • A new golden peel

Read more in the docs.

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.

Note

Paste or choose an image to add it.

Props

  • valuestring

    The content (controlled): HTML, or Markdown with format="markdown".

  • defaultValuestring
    Default: ''

    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'
    Default: 'html'

    What value holds. Markdown has no underline, colors or alignment.

  • toolbarToolbarItem[] | false
    Default: all of them

    The buttons, in order (a '|' entry is a divider), or false for none.

  • placeholderstring

    Shown while the editor is empty.

  • labelReactNode

    Label above the editor.

  • errorReactNode

    Error message below the editor; sets the invalid style.

  • helperTextReactNode

    Hint below the editor while there is no error.

  • minHeightnumber | string
    Default: '12rem'

    Minimum height of the writing area. A number is px.

  • maxHeightnumber | string

    Maximum height of the writing area; it scrolls beyond it.

  • disabledboolean
    Default: false

    Dim the editor and block editing.

  • readOnlyboolean
    Default: false

    Show the content without the toolbar and without editing.

  • fullScreenboolean

    Fill the whole window (controlled). The page behind does not scroll and Escape leaves it.

  • defaultFullScreenboolean
    Default: 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.

  • maxInlineImageSizenumber
    Default: 2000000

    Largest image, in bytes, that is embedded when there is no onImageUpload.

  • namestring

    Name for a hidden input that carries the value in a native <form>.

  • classNamestring
    Default: ''

    Extra classes for the root element.