@Mentions

Type @ followed by a name to tag a colleague, or #for a channel. Mentions render as atomic chips — you can click to select or delete the whole chip but can’t edit inside a name. Data sources are async (debounced, with a “Searching…” state) so they plug into your directory or user-search API cleanly.

Try it: type @al or #ann to see the picker.

Example code

<link rel="stylesheet" href="/richtexteditor/rte_theme_default.css" />
<script type="text/javascript" src="/richtexteditor/rte.js"></script>
<script type="text/javascript" src='/richtexteditor/plugins/all_plugins.js'></script>

<div id="mentions_editor">
    <p>Try it: type <strong>@al</strong> or <strong>#ann</strong> to see the picker.</p>
</div>

<script>
    var mentioncfg = { mentionEnabled: true, toolbar: "default" };
    var mentionEditor = new RichTextEditor("#mentions_editor", mentioncfg);

    // Fake directory — in production, call your own /api/users endpoint.
    var DIRECTORY = [
        { id: "alice", name: "Alice Lee", color: "#2563eb" },
        { id: "bob", name: "Bob Chen", color: "#dc2626" },
        { id: "carol", name: "Carol Diaz", color: "#16a34a" },
        { id: "maya", name: "Maya Patel", color: "#9333ea" }
    ];
    var CHANNELS = [
        { id: "announcements", name: "announcements" },
        { id: "product", name: "product" },
        { id: "engineering", name: "engineering" }
    ];

    if (mentionEditor.mentions) {
        mentionEditor.mentions.register({
            trigger: "@",
            insertClass: "rte-mention-person",
            search: function (q, done) {
                var rx = new RegExp(q, "i");
                setTimeout(function () { done(DIRECTORY.filter(function (p) { return rx.test(p.name); })); }, 150);
            }
        });
        mentionEditor.mentions.register({
            trigger: "#",
            insertClass: "rte-mention-channel",
            search: function (q, done) {
                done(CHANNELS.filter(function (c) { return c.name.indexOf(q.toLowerCase()) === 0; }));
            }
        });
    }
</script>