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>