Skip to content

Mentions & Tags

This sample demonstrate how to implement prosemirror-mentions in Ngx-Editor.

Install dependencies

Terminal window
npm i prosemirror-mentions

Make some code

Create Schema

import { marks, schema as baseSchema } from 'ngx-editor/schema';
import { Schema } from 'prosemirror-model';
import { addMentionNodes, addTagNodes } from 'prosemirror-mentions';
const schema = new Schema({
nodes: addTagNodes(addMentionNodes(baseSchema.spec.nodes)),
marks,
});
export default schema;

Include the plugins

import { Plugin } from 'prosemirror-state';
import { getMentionsPlugin } from 'prosemirror-mentions';
/**
* IMPORTANT: outer div's "suggestion-item-list" class is mandatory. The plugin uses this class for querying.
* IMPORTANT: inner div's "suggestion-item" class is mandatory too for the same reasons
*/
var getMentionSuggestionsHTML = (items) =>
'<div class="suggestion-item-list">' +
items
.map((i) => '<div class="suggestion-item">' + i.name + '</div>')
.join('') +
'</div>';
/**
* IMPORTANT: outer div's "suggestion-item-list" class is mandatory. The plugin uses this class for querying.
* IMPORTANT: inner div's "suggestion-item" class is mandatory too for the same reasons
*/
var getTagSuggestionsHTML = (items) =>
'<div class="suggestion-item-list">' +
items
.map((i) => '<div class="suggestion-item">' + i.tag + '</div>')
.join('') +
'</div>';
const users = [
{
name: 'John Doe',
id: '101',
email: 'joe@gmail.com',
},
{
name: 'Joe Lewis',
id: '102',
email: 'lewis@gmail.com',
},
];
var mentionPlugin = getMentionsPlugin({
getSuggestions: (type, text, done) => {
setTimeout(() => {
if (type === 'mention') {
// autocomplete : filter list from text and return 5 users
done(
users
.filter((x) => x.name.toLowerCase().includes(text.toLowerCase()))
.splice(0, 5),
);
} else {
// pass dummy tag suggestions
done([
{
tag: 'WikiLeaks',
},
{
tag: 'NetNeutrality',
},
]);
}
}, 0);
},
getSuggestionsHTML: (items, type) => {
if (type === 'mention') {
return getMentionSuggestionsHTML(items);
} else if (type === 'tag') {
return getTagSuggestionsHTML(items);
} else {
return null;
}
},
});
const getPlugins = (): Plugin[] => {
const plugins = [mentionPlugin];
return plugins;
};
export default getPlugins();

Editor Component

new Editor({
schema,
plugins,
});

Include some styles

.prosemirror-mention-node {
color: blue !important;
text-decoration: underline !important;
}
.prosemirror-tag-node {
color: gray !important;
font-style: italic;
}
.suggestion-item-list {
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
z-index: 1;
}
.suggestion-item {
color: black;
padding: 12px 16px;
text-decoration: none;
display: block;
}
.suggestion-item:hover {
background-color: #f1f1f1;
cursor: pointer;
}