Dojo NG is being built in the open, one section at a time — follow along on Heptapod.

API REFERENCE · RICH TEXT PLUGINS

@dojo-ng/rich-text-mentions

@mentions for <dj-rich-text>: type @ and pick a person from a menu.

Try it in the playground

@dojo-ng/rich-text-mentions · v0.1.1 · A plugin for <dj-rich-text>, not a custom element

npm install @dojo-ng/rich-text-mentions

Compose the mentions plugin with the default set and supply a source. Here it filters a static list; in production, call your directory API.

<dj-rich-text id="editor" label="Comment"></dj-rich-text>
<script type="module">
  import "@dojo-ng/rich-text";
  import { defaultPlugins } from "@dojo-ng/rich-text";
  import { createMentionsPlugin } from "@dojo-ng/rich-text-mentions";
  const PEOPLE = [{ id: "u1", label: "Jeff" }, { id: "u2", label: "Esther" }];
  const mentions = createMentionsPlugin({
    source: async (q) => PEOPLE.filter((p) => p.label.toLowerCase().includes(q.toLowerCase())),
  });
  document.getElementById("editor").plugins = [...defaultPlugins, mentions];
</script>

Using it

  • Typing the trigger (@ by default) opens a menu at the caret. ArrowUp and ArrowDown move the highlight; Enter, Tab, or a click inserts the mention and a space; Escape closes the menu.
  • A mention is one unit: it shows as @label and Backspace deletes it whole.

Setup

  • source is required and comes from your app: source(query) => Promise<Array<{ id, label }>>. It is called after a short delay, older answers are ignored, and a spinner shows while it loads.
  • Because source is required, there is no ready-made mentionsPlugin. Use createMentionsPlugin({ source, trigger? }).
  • Also exports MentionNode, $createMentionNode, $isMentionNode, and DEFAULT_MENTION_TRIGGER.
  • Setting plugins replaces the default set, so spread ...defaultPlugins to keep bold, italic, underline, undo, and redo.

HTML and pasting

  • Mentions survive the value round trip as <span data-dj-mention="id">@label</span>.
  • Paste cleaning keeps the span but removes its attributes, so a pasted mention becomes plain @label text.

Not built

  • More than one trigger character, hover cards, editing a mention in place, and guidance for server-side rendering.

Need one of these? Make a request on Discord or add an issue (work item) on Heptapod.

Functions

createMentionsPlugin

function createMentionsPlugin(options: MentionsPluginOptions): RichTextPlugin;

Classes

MentionNode

class MentionNode extends TextNode {
  __id: string;
  static getType(): string;
  static clone(node: MentionNode): MentionNode;
  constructor(id: string, text: string, key?: NodeKey);
  getId(): string;
  createDOM(config: EditorConfig): HTMLElement;
  exportDOM(): DOMExportOutput;
  static importDOM(): DOMConversionMap | null;
  exportJSON(): SerializedMentionNode;
  static importJSON(serializedNode: SerializedMentionNode): MentionNode;
  canInsertTextBefore(): boolean;
  canInsertTextAfter(): boolean;
  isTextEntity(): boolean;
}

Values

DEFAULT_MENTION_TRIGGER

const DEFAULT_MENTION_TRIGGER: RegExp;

Types

MentionsPluginOptions

interface MentionsPluginOptions {
  source: (query: string) => Promise<Array<{
    id: string;
    label: string;
  }>>;
  trigger?: RegExp;
}

SerializedMentionNode

type SerializedMentionNode = Spread<{
  id: string;
}, SerializedTextNode>;