Chat Composer

The same engine as every other demo on this site, shaped as a message box: a short toolbar, an auto-growing height, Enter to send and Shift+Enter for a new line. Every message is passed through editor.sanitizeHtml()before it is rendered into the thread — a chat app is exactly where untrusted rich text arrives.

AD
Ada K.

The composer should accept formatting but stay compact until you need more.

TO
Tom M.

Agreed. Enter sends — Shift+Enter makes a new line.

Enter to send · Shift+Enter for a new line · try pasting rich text

Example code

<div id="composer" style="height:44px"></div>

<script>
  var cfg = RTE_CreateConfig();

  // config.toolbar names a SET: the core resolves config["toolbar_" + value].
  // There is no "custom" value - a name that does not resolve silently leaves
  // the full document toolbar in place.
  cfg.toolbar = "chat";
  cfg.toolbar_chat = "{bold,italic,strike}|{insertlink,insertblockquote,insertemoji}|{removeformat}";
  cfg.showPlusButton = false;
  cfg.autoGrow = true;              // height itself is CSS on the host element
  cfg.placeholder = "Message #product-design";

  var editor = new RichTextEditor("#composer", cfg);

  // Enter sends; Shift+Enter inserts a line break.
  // Bound to the editable ELEMENT: the editor's event bus carries
  // ready/change/selectionchange/keyup, not "keydown".
  editor.getEditable().addEventListener("keydown", function (e) {
    if (e.key === "Enter" && !e.shiftKey) {
      e.preventDefault();
      send(editor.getHTML());
      editor.setHTML("");
    }
  }, true);

  // A chat app is where untrusted rich text lands. sanitizeHtml() lives in
  // plugins/sanitizer.js, not the core - it strips inline handlers and
  // javascript: URLs while keeping the text.
  function send(html) {
    thread.innerHTML += editor.sanitizeHtml(html);
  }
</script>