Mention Support in Blazor Markdown Editor Component
18 Mar 202515 minutes to read
By integrating the Mention component with the Markdown Editor, users can effortlessly mention or tag other users or objects from a suggested list. This eliminates the need to manually type out names or identifying information, improving both efficiency and accuracy.
Enabling Mention in Blazor Markdown Editor
To enable the Mention functionality within the Markdown Editor, set the Target property of the Mention component to the ID of the textarea element inside the editor. When specifying the target, ensure that you append the suffix _editable-content
to the ID. This configuration allows users to mention or tag others from the suggested list while editing text.
When a user types the @
symbol followed by a character, the Markdown Editor displays a list of suggestions. Users can select an item from the list by either clicking on it or typing the desired name.
Configuring Mention Properties
The Syncfusion Mention component provides several customizable properties to enhance the tagging experience:
- AllowSpaces - Allow to continue search action if user enter space after mention character while searching.
- SuggestionCount - The maximum number of items that will be displayed in the suggestion list.
- ItemTemplate - Used to display the customized appearance in suggestion list.
Example: Implementing Mention in Markdown Editor
The following example demonstrates how to enable Mention support in the Blazor Markdown Editor.
@using Syncfusion.Blazor.RichTextEditor
@using Syncfusion.Blazor.DropDowns
@using Markdig;
<div class="control-section">
@if (!IsPreview)
{
<SfMention TItem="PersonData" ID="RT_Editor_mention" Target="#MD_Editor_editable-content" DataSource="@EmailData" SortOrder="SortOrder.Ascending" AllowSpaces="true" PopupHeight="200px" PopupWidth="250px">
<ItemTemplate>
<div class="editor-mention-item-template">
<div class="em-header">
<div class="em-avatar" style="background-color: @((context as PersonData).BgColor); color: @((context as PersonData).Color);">
<div class="em-initial">@((context as PersonData).Initial)</div>
</div>
</div>
<div class="em-content">
<div class="em-name">@((context as PersonData).Name)</div>
<div class="em-email">@((context as PersonData).Email)</div>
</div>
</div>
</ItemTemplate>
<DisplayTemplate>
[@@@((context as PersonData).Name)](mailto:@((context as PersonData).Email))
</DisplayTemplate>
<ChildContent>
<MentionFieldSettings Text="Name"></MentionFieldSettings>
</ChildContent>
</SfMention>
<SfRichTextEditor ID="MD_Editor" Width="700px" Height="250px" EditorMode="EditorMode.Markdown" SaveInterval="1" @bind-Value="@MarkdownValue">
<RichTextEditorToolbarSettings Items="@Tools">
<RichTextEditorCustomToolbarItems>
<RichTextEditorCustomToolbarItem Name="Preview">
<Template>
<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn" @onclick="PreviewClick">
<span class="e-btn-icon e-md-preview e-icons"></span>
</button>
</Template>
</RichTextEditorCustomToolbarItem>
</RichTextEditorCustomToolbarItems>
</RichTextEditorToolbarSettings>
<RichTextEditorMarkdownOptions ListSyntax="@ListSyntax" />
<RichTextEditorEvents ValueChange="@OnValueChange" />
</SfRichTextEditor>
}
else
{
<SfRichTextEditor Readonly="true" @bind-Value="@HtmlValue">
<RichTextEditorToolbarSettings Items="@Items">
<RichTextEditorCustomToolbarItems>
<RichTextEditorCustomToolbarItem Name="code">
<Template>
<button id="MD_Preview" class="e-tbar-btn e-control e-btn e-icon-btn" @onclick="CodeClick">
<span class="e-btn-icon e-preview e-icons"></span>
</button>
</Template>
</RichTextEditorCustomToolbarItem>
</RichTextEditorCustomToolbarItems>
</RichTextEditorToolbarSettings>
</SfRichTextEditor>
}
</div>
@code{
private bool IsPreview { get; set; }
private string HtmlValue { get; set; }
private MarkdownPipeline Pipeline { get; set; }
private string MarkdownValue { get; set; } =@"Hello [@Albert](mailto:[email protected])
Welcome to the mention integration with markdown editor demo. Type @ character and tag user from the suggestion list.";
private List<ToolbarItemModel> Items = new List<ToolbarItemModel>()
{
new ToolbarItemModel() { Name = "code", TooltipText = "Code View" },
};
private List<ToolbarItemModel> Tools = new List<ToolbarItemModel>()
{
new ToolbarItemModel() { Command = ToolbarCommand.Bold },
new ToolbarItemModel() { Command = ToolbarCommand.Italic },
new ToolbarItemModel() { Command = ToolbarCommand.StrikeThrough },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Command = ToolbarCommand.Formats },
new ToolbarItemModel() { Command = ToolbarCommand.Blockquote },
new ToolbarItemModel() { Command = ToolbarCommand.OrderedList },
new ToolbarItemModel() { Command = ToolbarCommand.UnorderedList },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Command = ToolbarCommand.CreateLink },
new ToolbarItemModel() { Command = ToolbarCommand.Image },
new ToolbarItemModel() { Command = ToolbarCommand.CreateTable },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Name = "Preview", TooltipText = "Preview" },
new ToolbarItemModel() { Command = ToolbarCommand.Undo },
new ToolbarItemModel() { Command = ToolbarCommand.Redo }
};
private Dictionary<string, string> ListSyntax { get; set; } = new Dictionary<string, string>()
{
{ "OL", "1., 2., 3." }
};
protected override void OnInitialized()
{
Pipeline = new MarkdownPipelineBuilder().UseAdvancedExtensions().Build();
this.HtmlValue = Markdig.Markdown.ToHtml(MarkdownValue, Pipeline);
base.OnInitialized();
}
private void OnValueChange(Syncfusion.Blazor.RichTextEditor.ChangeEventArgs args)
{
if (args.Value == null)
{
this.HtmlValue = null;
}
else
{
this.HtmlValue = Markdig.Markdown.ToHtml(args.Value, Pipeline);
}
}
private void PreviewClick()
{
Items = new List<ToolbarItemModel>()
{
new ToolbarItemModel() { Name = "code", TooltipText = "Code View" },
};
this.IsPreview = true;
}
private void CodeClick()
{
Tools = new List<ToolbarItemModel>()
{
new ToolbarItemModel() { Command = ToolbarCommand.Bold },
new ToolbarItemModel() { Command = ToolbarCommand.Italic },
new ToolbarItemModel() { Command = ToolbarCommand.StrikeThrough },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Command = ToolbarCommand.Formats },
new ToolbarItemModel() { Command = ToolbarCommand.Blockquote },
new ToolbarItemModel() { Command = ToolbarCommand.OrderedList },
new ToolbarItemModel() { Command = ToolbarCommand.UnorderedList },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Command = ToolbarCommand.CreateLink },
new ToolbarItemModel() { Command = ToolbarCommand.Image },
new ToolbarItemModel() { Command = ToolbarCommand.CreateTable },
new ToolbarItemModel() { Command = ToolbarCommand.Separator },
new ToolbarItemModel() { Name = "Preview", TooltipText = "Preview" },
new ToolbarItemModel() { Command = ToolbarCommand.Undo },
new ToolbarItemModel() { Command = ToolbarCommand.Redo }
};
this.IsPreview = false;
}
public class PersonData
{
public string Name { get; set; }
public string Initial { get; set; }
public string Email { get; set; }
public string Color { get; set; }
public string BgColor { get; set; }
}
private List<PersonData> EmailData = new List<PersonData>
{
new PersonData() { Name = "Selma Rose", Initial = "SR", Email = "[email protected]", Color = "#FAFDFF", BgColor = "#01579B" },
new PersonData() { Name = "Maria", Initial = "MA", Email = "[email protected]", Color = "#004378", BgColor = "#ADDBFF" },
new PersonData() { Name = "Russo Kay", Initial = "RK", Email = "[email protected]", Color = "#F9DEDC", BgColor = "#8C1D18" },
new PersonData() { Name = "Robert", Initial = "RO", Email = "[email protected]", Color = "#FFD6F7", BgColor = "#37003A" },
new PersonData() { Name = "Camden Kate", Initial = "CK", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#464ECF" },
new PersonData() { Name = "Garth", Initial = "GA", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#008861" },
new PersonData() { Name = "Andrew James", Initial = "AJ", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#53CA17" },
new PersonData() { Name = "Olivia", Initial = "OL", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#8C1D18" },
new PersonData() { Name = "Sophia", Initial = "SO", Email = "[email protected]", Color = "#000000", BgColor = "#D0BCFF" },
new PersonData() { Name = "Margaret", Initial = "MA", Email = "[email protected]", Color = "#000000", BgColor = "#F2B8B5" },
new PersonData() { Name = "Ursula Ann", Initial = "UA", Email = "[email protected]", Color = "#000000", BgColor = "#47ACFB" },
new PersonData() { Name = "Laura Grace", Initial = "LG", Email = "[email protected]", Color = "#000000", BgColor = "#FFE088" },
new PersonData() { Name = "Albert", Initial = "AL", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#00335B" },
new PersonData() { Name = "William", Initial = "WA", Email = "[email protected]", Color = "#FFFFFF", BgColor = "#163E02" }
};
}
<style>
.e-content td,
.e-content th {
border: 1px solid #bdbdbd;
padding: 0 5px;
}
.e-icon-btn .e-md-preview::before {
content: '\e7de';
}
.e-icon-btn .e-preview::before {
content: '\e80e';
}
.editor-mention-item-template {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
align-items: center;
}
.em-content {
display: flex;
flex-direction: column;
justify-content: center;
}
.em-avatar {
width: 32px;
height: 32px;
text-align: center;
border-radius: 50%;
font-size: 12px;
font-weight: 500;
text-indent: 0px;
line-height: 13px;
color: #fff;
display: flex;
align-items: center;
justify-content: center;
}
.em-name {
color: rgb(16, 24, 40);
font-size: 14px;
font-weight: 400;
line-height: 14px;
margin-bottom: 5px;
}
.em-email {
color: gray;
font-size: 12px;
font-weight: 400;
line-height: 14px;
}
#RT_Editor_mention_options li {
padding: 10px;
height: 60px;
}
body[class*="-dark"] .em-name {
color: #fff !important;
}
</style>