Mentions in Editor
Environment
| Product | Editor for Blazor |
Description
How to enable or implement support for @mentions in the TelerikEditor for Blazor, similar to GitHub, Facebook, etc.?
Solution
You can use the proseMirror-mentions plugin to provide a @mentions and #hashtags functionality for the Telerik Blazor Editor component. To implement the feature, customize the built-in ProseMirror schema and integrate a ProseMirror plugin.
For dynamic positioning of the mentions list, set the EditMode property of the Editor to EditorEditorMode.Div. This ensures that the mentions dropdown position is correct relative to the Editor content.
<TelerikEditor EditMode="EditorEditMode.Div" />
Setting up WebPack and Installing proseMirror-mentions
- Setup the Javascript project by running the following command in the root folder of your project:
SH
npm init -yThis command creates a
package.jsonfile with the project's configuration. The-yflag accepts all defaults for simplicity. In a real world application, consider runningnpm initwithout the flag to configure settings interactively. - Install a JavaScript bundler. In this example we will use webpack, so run:
SH
npm install webpack webpack-cli --save-dev - Configure the build script in the
scriptssection ofpackage.json(in this example all of our Javascript files will go intowwwroot/js):JSON"scripts": { "build": "webpack ./wwwroot/js/index.js --output-path ./wwwroot/js --output-filename index.bundle.js" }, - Update the module type in
package.json:This enables ES6JSON"type": module"import/exportsyntax instead of the CommonJS require statements which will be useful later on. - Install proseMirror-mentions by running:
SH
npm install prosemirror-mentions - Create a file named
index.jsin your project'swwwroot/jsdirectory and paste the contents from the respective code tab below. - Build the JavaScript bundle by running:
This creates theSH
npm run buildindex.bundle.jsfile in yourwwwroot/jsdirectory.
Include the JavaScript Bundle
After building the JavaScript bundle, you need to include it in your Blazor application:
Global Level (App.razor):
<!DOCTYPE html>
<html>
<head>
<!-- other head content -->
</head>
<body>
<!-- body content -->
<script src="js/index.bundle.js"></script>
</body>
</html>
Integrate the Mentions Plugin
The following code demonstrates how to integrate the proseMirror-mentions plugin in the Editor.
@using Microsoft.Extensions.Logging.Abstractions
@implements IDisposable
@inject IJSRuntime JSRuntime
@inject IServiceProvider ServiceProvider
<TelerikEditor Plugins="pluginsProvider"
Schema="schemaProvider"
EditMode="EditorEditMode.Div">
</TelerikEditor>
@code {
// Replace Component with your actual component type
private DotNetObjectReference<Component>? dotNetRef;
private List<Mention> Mentions { get; set; } = new List<Mention>()
{
new()
{
Id = "board",
Name = "Jane Simons",
Email = "jane.simons@company.com",
},
new()
{
Id = "engineering",
Name = "Peter Parker",
Email = "peter.parker@company.com"
},
new()
{
Id = "generalManager",
Name = "Liam Turner",
Email = "liam.turner@company.com"
}
};
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
dotNetRef = DotNetObjectReference.Create(this);
await JSRuntime.InvokeVoidAsync("initializeMentions", dotNetRef);
}
}
[JSInvokable]
public async Task<Mention[]> GetMentionSuggestionsAsync(string text)
{
return Mentions.Where(mention => mention.Name.ToLower().Contains(text)).ToArray();
}
[JSInvokable]
public async Task<string> GetMentionSuggestionsHTML(List<Mention> mentions)
{
using var htmlRenderer = new HtmlRenderer(ServiceProvider, NullLoggerFactory.Instance);
var html = await htmlRenderer.Dispatcher.InvokeAsync(async () =>
{
var dictionary = new Dictionary<string, object?>
{
{ "Items", mentions }
};
var parameters = ParameterView.FromDictionary(dictionary);
var output = await htmlRenderer.RenderComponentAsync<MentionSuggestionList>(parameters);
return output.ToHtmlString();
});
return html;
}
public void Dispose()
{
dotNetRef?.Dispose();
}
}