Mention Support in React Markdown Editor Component
4 Sep 202524 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 React 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 - Defines the maximum number of items displayed in the suggestion list.
- itemTemplate - Customizes the appearance of items in the suggestion list.
Example: Implementing mention in markdown editor
The following example demonstrates how to enable Mention support in the React Markdown Editor.
[Class-component]
import { createElement } from '@syncfusion/ej2-base';
import { Image, Inject, Link, Table, MarkdownEditor, MarkdownFormatter, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';
import { MentionComponent } from '@syncfusion/ej2-react-dropdowns';
class App extends React.Component {
rteObj;
mention;
value = 'Hello [@Maria](mailto:[email protected])\n\nWelcome to the mention integration with markdown editor demo. Type @ character and tag user from the suggestion list.';
items = ['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable',
{
tooltipText: 'Preview',
template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn" aria-label="Preview Code">' +
'<span class="e-btn-icon e-md-preview e-icons"></span></button>'
}, '|', 'Undo', 'Redo'];
textArea;
mdsource;
emailData = [
{ name: "Selma Rose", initial: 'SR', email: "[email protected]", color: '#FAFDFF', bgColor: '#01579B' },
{ name: "Maria", initial: 'MA', email: "[email protected]", color: '#004378', bgColor: '#ADDBFF' },
{ name: "Russo Kay", initial: 'RK', email: "[email protected]", color: '#F9DEDC', bgColor: '#8C1D18' },
{ name: "Robert", initial: 'RO', email: "[email protected]", color: '#FFD6F7', bgColor: '#37003A' },
{ name: "Camden Kate", initial: 'CK', email: "[email protected]", color: '#FFFFFF', bgColor: '#464ECF' },
{ name: "Garth", initial: 'GA', email: "[email protected]", color: '#FFFFFF', bgColor: '#008861' },
{ name: "Andrew James", initial: 'AJ', email: "[email protected]", color: '#FFFFFF', bgColor: '#53CA17' },
{ name: "Olivia", initial: 'OL', email: "[email protected]", color: '#FFFFFF', bgColor: '#8C1D18' },
{ name: "Sophia", initial: 'SO', email: "[email protected]", color: '#000000', bgColor: '#D0BCFF' },
{ name: "Margaret", initial: 'MA', email: "[email protected]", color: '#000000', bgColor: '#F2B8B5' },
{ name: "Ursula Ann", initial: 'UA', email: "[email protected]", color: '#000000', bgColor: '#47ACFB' },
{ name: "Laura Grace", initial: 'LG', email: "[email protected]", color: '#000000', bgColor: '#FFE088' },
{ name: "Albert", initial: 'AL', email: "[email protected]", color: '#FFFFFF', bgColor: '#00335B' },
{ name: "William", initial: 'WA', email: "[email protected]", color: '#FFFFFF', bgColor: '#163E02' }
];
toolbarSettings = {
items: this.items
};
formatter = new MarkdownFormatter({ listTags: { 'OL': '1., 2., 3.' } });
markdownConversion() {
if (this.mdsource.classList.contains('e-active')) {
let id = this.rteObj.getID() + 'html-view';
let htmlPreview = this.rteObj.element.querySelector('#' + id);
htmlPreview.innerHTML = Marked(this.rteObj.contentModule.getEditPanel().value);
}
}
fullPreview() {
let id = this.rteObj.getID() + 'html-preview';
let htmlPreview = this.rteObj.element.querySelector('#' + id);
if (this.mdsource.classList.contains('e-active')) {
this.mdsource.classList.remove('e-active');
this.mdsource.parentElement.title = 'Preview';
this.textArea.style.display = 'block';
htmlPreview.style.display = 'none';
}
else {
this.mdsource.classList.add('e-active');
if (!htmlPreview) {
htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
htmlPreview.id = id;
this.textArea.parentNode.appendChild(htmlPreview);
}
this.textArea.style.display = 'none';
htmlPreview.style.display = 'block';
htmlPreview.innerHTML = Marked(this.rteObj.contentModule.getEditPanel().value);
this.mdsource.parentElement.title = 'Code View';
}
}
rendereComplete() {
if (!this.rteObj) {
return;
}
this.textArea = this.rteObj.contentModule.getEditPanel();
this.textArea.addEventListener('keyup', (e) => {
this.markdownConversion();
});
this.mdsource = document.getElementById('preview-code');
this.mdsource.addEventListener('click', (e) => {
this.fullPreview();
if (e.currentTarget.classList.contains('e-active')) {
this.rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo']);
}
else {
this.rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo']);
}
});
}
itemTemplate(data) {
return (<div className="editor-mention-item-template">
<div className="em-header">
<div className="em-avatar" style=>
<div className="em-initial">{data.initial}</div>
</div>
</div>
<div className="em-content">
<div className="em-name">{data.name}</div>
<div className="em-email">{data.email}</div>
</div>
</div>);
}
displayTemplate(data) {
return (<React.Fragment>
[@{data.name}](mailto:${data.email})
</React.Fragment>);
}
render() {
return (
<div className='control-section' id="rteMarkdown">
<div className="content-wrapper">
<RichTextEditorComponent id="markdownRTE" ref={(richtexteditor) => { this.rteObj = richtexteditor; }} created={this.rendereComplete} editorMode='Markdown' height='250px' value={this.value} formatter={this.formatter} toolbarSettings={this.toolbarSettings}>
<Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]}/>
</RichTextEditorComponent>
<MentionComponent id='editorMention' ref={(mention) => { this.mention = mention; }} dataSource={this.emailData} displayTemplate={this.displayTemplate} itemTemplate={this.itemTemplate} target="#markdownRTE_editable-content" fields= popupWidth='250px' popupHeight='200px' sortOrder='Ascending' allowSpaces={true}></MentionComponent>
</div>
</div>);
}
}
export default App;import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import { Image, Inject, Link, Table, MarkdownEditor, IToolbarItems, ToolbarSettingsModel, MarkdownFormatter, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';
import { MentionComponent } from '@syncfusion/ej2-react-dropdowns';
class App extends React.Component<{},{}> {
private rteObj: RichTextEditorComponent;
private mention: MentionComponent;
// set the value to Rich Text Editor
private value: string = 'Hello [@Maria](mailto:[email protected])\n\nWelcome to the mention integration with markdown editor demo. Type @ character and tag user from the suggestion list.';
// Rich Text Editor items list
private items: (string | IToolbarItems)[] = ['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', 'SuperScript', 'SubScript', '|',
'CreateLink', 'Image', 'CreateTable', '|',
{
tooltipText: 'Preview',
template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn" aria-label="Preview Code">' +
'<span class="e-btn-icon e-md-preview e-icons"></span></button>'
}, '|', 'Undo', 'Redo'];
private textArea: HTMLTextAreaElement;
private mdsource: HTMLElement;
private mdPreview: HTMLElement;
private emailData: { [key: string]: string; }[] = [
{ name: "Selma Rose", initial: 'SR', email: "[email protected]", color: '#FAFDFF', bgColor: '#01579B' },
{ name: "Maria", initial: 'MA', email: "[email protected]", color: '#004378', bgColor: '#ADDBFF' },
{ name: "Russo Kay", initial: 'RK', email: "[email protected]", color: '#F9DEDC', bgColor: '#8C1D18' },
{ name: "Robert", initial: 'RO', email: "[email protected]", color: '#FFD6F7', bgColor: '#37003A' },
{ name: "Camden Kate", initial: 'CK', email: "[email protected]", color: '#FFFFFF', bgColor: '#464ECF' },
{ name: "Garth", initial: 'GA', email: "[email protected]", color: '#FFFFFF', bgColor: '#008861' },
{ name: "Andrew James", initial: 'AJ', email: "[email protected]", color: '#FFFFFF', bgColor: '#53CA17' },
{ name: "Olivia", initial: 'OL', email: "[email protected]", color: '#FFFFFF', bgColor: '#8C1D18' },
{ name: "Sophia", initial: 'SO', email: "[email protected]", color: '#000000', bgColor: '#D0BCFF' },
{ name: "Margaret", initial: 'MA', email: "[email protected]", color: '#000000', bgColor: '#F2B8B5' },
{ name: "Ursula Ann", initial: 'UA', email: "[email protected]", color: '#000000', bgColor: '#47ACFB' },
{ name: "Laura Grace", initial: 'LG', email: "[email protected]", color: '#000000', bgColor: '#FFE088' },
{ name: "Albert", initial: 'AL', email: "[email protected]", color: '#FFFFFF', bgColor: '#00335B' },
{ name: "William", initial: 'WA', email: "[email protected]", color: '#FFFFFF', bgColor: '#163E02' }
];
//Rich Text Editor ToolbarSettings
private toolbarSettings: ToolbarSettingsModel = {
items: this.items
};
private formatter: MarkdownFormatter = new MarkdownFormatter({ listTags: { 'OL': '1., 2., 3.' } });
public markdownConversion() {
if (this.mdsource.classList.contains('e-active')) {
let id: string = this.rteObj.getID() + 'html-view';
let htmlPreview: HTMLElement = this.rteObj.element.querySelector('#' + id);
htmlPreview.innerHTML = Marked.marked((this.rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
}
}
public fullPreview() {
let id: string = this.rteObj.getID() + 'html-preview';
let htmlPreview: HTMLElement = this.rteObj.element.querySelector('#' + id);
if (this.mdsource.classList.contains('e-active')) {
this.mdsource.classList.remove('e-active');
this.mdsource.parentElement.title = 'Preview';
this.textArea.style.display = 'block';
htmlPreview.style.display = 'none';
} else {
this.mdsource.classList.add('e-active');
if (!htmlPreview) {
htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
htmlPreview.id = id;
this.textArea.parentNode.appendChild(htmlPreview);
}
this.textArea.style.display = 'none';
htmlPreview.style.display = 'block';
htmlPreview.innerHTML = Marked.marked((this.rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
this.mdsource.parentElement.title = 'Code View';
}
}
public rendereComplete() {
if (!this.rteObj) {
return;
}
this.textArea = this.rteObj.contentModule.getEditPanel() as HTMLTextAreaElement;
this.textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
this.markdownConversion();
});
this.mdsource = document.getElementById('preview-code');
this.mdsource.addEventListener('click', (e: MouseEvent) => {
this.fullPreview();
if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
this.rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
'UnorderedList', 'SuperScript', 'SubScript', 'CreateLink', 'Image', 'CreateTable', 'Formats', 'Undo', 'Redo']);
} else {
this.rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', 'OrderedList',
'UnorderedList', 'SuperScript', 'SubScript', 'CreateLink', 'Image', 'CreateTable', 'Formats', 'Undo', 'Redo']);
}
});
}
private itemTemplate(data: any) {
return (
<div className="editor-mention-item-template">
<div className="em-header">
<div className="em-avatar" style=>
<div className="em-initial">{data.initial}</div>
</div>
</div>
<div className="em-content">
<div className="em-name">{data.name}</div>
<div className="em-email">{data.email}</div>
</div>
</div>
);
}
private displayTemplate(data: any){
return (
<React.Fragment>
[@{data.name}](mailto:${data.email})
</React.Fragment>
);
}
public render() {
return (
<div className='control-section' id="rteMarkdown">
<div className="content-wrapper">
<RichTextEditorComponent id="markdownRTE"
ref={(richtexteditor) => { this.rteObj = richtexteditor }} editorMode='Markdown'
height='250px' value={this.value} formatter={this.formatter} toolbarSettings={this.toolbarSettings} created={this.rendereComplete} >
<Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
</RichTextEditorComponent>
<MentionComponent id='editorMention' ref={(mention: MentionComponent) => { this.mention = mention }} dataSource={this.emailData} displayTemplate={this.displayTemplate} itemTemplate={this.itemTemplate} target="#markdownRTE_editable-content" fields= popupWidth='250px' popupHeight='200px' sortOrder='Ascending' allowSpaces={true}></MentionComponent>
</div>
</div>
);
}
}
export default App;[Functional-component]
import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import { Image, Inject, Link, Table, MarkdownEditor, IToolbarItems, ToolbarSettingsModel, MarkdownFormatter, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';
import { MentionComponent } from '@syncfusion/ej2-react-dropdowns';
function App() {
let rteObj;
const value =
'Hello [@Maria](mailto:[email protected])\n\nWelcome to the mention integration with markdown editor demo. Type @ character and tag user from the suggestion list.';
const items = [
'Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable',
{
tooltipText: 'Preview',
template:
'<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn" aria-label="Preview Code" >' +
'<span class="e-btn-icon e-md-preview e-icons"></span></button>',
},
'|',
'Undo',
'Redo',
];
let textArea;
let mdsource;
const emailData = [
{
name: 'Selma Rose',
initial: 'SR',
email: '[email protected]',
color: '#FAFDFF',
bgColor: '#01579B',
},
{
name: 'Maria',
initial: 'MA',
email: '[email protected]',
color: '#004378',
bgColor: '#ADDBFF',
},
{
name: 'Russo Kay',
initial: 'RK',
email: '[email protected]',
color: '#F9DEDC',
bgColor: '#8C1D18',
},
{
name: 'Robert',
initial: 'RO',
email: '[email protected]',
color: '#FFD6F7',
bgColor: '#37003A',
},
{
name: 'Camden Kate',
initial: 'CK',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#464ECF',
},
{
name: 'Garth',
initial: 'GA',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#008861',
},
{
name: 'Andrew James',
initial: 'AJ',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#53CA17',
},
{
name: 'Olivia',
initial: 'OL',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#8C1D18',
},
{
name: 'Sophia',
initial: 'SO',
email: '[email protected]',
color: '#000000',
bgColor: '#D0BCFF',
},
{
name: 'Margaret',
initial: 'MA',
email: '[email protected]',
color: '#000000',
bgColor: '#F2B8B5',
},
{
name: 'Ursula Ann',
initial: 'UA',
email: '[email protected]',
color: '#000000',
bgColor: '#47ACFB',
},
{
name: 'Laura Grace',
initial: 'LG',
email: '[email protected]',
color: '#000000',
bgColor: '#FFE088',
},
{
name: 'Albert',
initial: 'AL',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#00335B',
},
{
name: 'William',
initial: 'WA',
email: '[email protected]',
color: '#FFFFFF',
bgColor: '#163E02',
},
];
const toolbarSettings = {
items: items,
};
const formatter = new MarkdownFormatter({ listTags: { OL: '1., 2., 3.' } });
function markdownConversion() {
if (mdsource.classList.contains('e-active')) {
let id = rteObj.getID() + 'html-view';
let htmlPreview = rteObj.element.querySelector('#' + id);
htmlPreview.innerHTML = Marked.marked(
rteObj.contentModule.getEditPanel().value
);
}
}
function fullPreview() {
let id = rteObj.getID() + 'html-preview';
let htmlPreview = rteObj.element.querySelector('#' + id);
if (mdsource.classList.contains('e-active')) {
mdsource.classList.remove('e-active');
mdsource.parentElement.title = 'Preview';
textArea.style.display = 'block';
htmlPreview.style.display = 'none';
} else {
mdsource.classList.add('e-active');
if (!htmlPreview) {
htmlPreview = createElement('div', {
className: 'e-content e-pre-source',
});
htmlPreview.id = id;
textArea.parentNode.appendChild(htmlPreview);
}
textArea.style.display = 'none';
htmlPreview.style.display = 'block';
htmlPreview.innerHTML = Marked.marked(
rteObj.contentModule.getEditPanel().value
);
mdsource.parentElement.title = 'Code View';
}
}
function rendereComplete() {
textArea = rteObj.contentModule.getEditPanel();
textArea.addEventListener('keyup', (e) => {
markdownConversion();
});
mdsource = document.getElementById('preview-code');
mdsource.addEventListener('click', (e) => {
fullPreview();
if (e.currentTarget.classList.contains('e-active')) {
rteObj.disableToolbarItem([
'Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo'
]);
} else {
rteObj.enableToolbarItem([
'Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo'
]);
}
});
}
function itemTemplate(data) {
return (
<div className="editor-mention-item-template">
<div className="em-header">
<div
className="em-avatar"
style=
>
<div className="em-initial">{data.initial}</div>
</div>
</div>
<div className="em-content">
<div className="em-name">{data.name}</div>
<div className="em-email">{data.email}</div>
</div>
</div>
);
}
function displayTemplate(data) {
return (
<React.Fragment>
[@{data.name}](mailto:${data.email})
</React.Fragment>
);
}
return ( <div className="control-section" id="rteMarkdown">
<div className="content-wrapper">
<RichTextEditorComponent
id="markdownRTE"
ref={(richtexteditor) => {
rteObj = richtexteditor;
}}
editorMode="Markdown"
height="250px"
value={value}
formatter={formatter}
created={rendereComplete}
toolbarSettings={toolbarSettings}
>
<Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
</RichTextEditorComponent>
<MentionComponent
id="editorMention"
ref={(mention) => {
mention = mention;
}}
dataSource={emailData}
displayTemplate={displayTemplate}
itemTemplate={itemTemplate}
target="#markdownRTE_editable-content"
fields=
popupWidth="250px"
popupHeight="200px"
sortOrder="Ascending"
allowSpaces={true}
></MentionComponent>
</div>
</div>);
}
export default App;import { createElement, KeyboardEventArgs } from '@syncfusion/ej2-base';
import { Image, Inject, Link, Table, MarkdownEditor, IToolbarItems, ToolbarSettingsModel, MarkdownFormatter, RichTextEditorComponent, Toolbar } from '@syncfusion/ej2-react-richtexteditor';
import * as React from 'react';
import * as Marked from 'marked';
import { MentionComponent } from '@syncfusion/ej2-react-dropdowns';
function App(){
let rteObj: RichTextEditorComponent;
const value: string = 'Hello [@Maria](mailto:[email protected])\n\nWelcome to the mention integration with markdown editor demo. Type @ character and tag user from the suggestion list.';
const items: (string | IToolbarItems)[] = ['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable',
{
tooltipText: 'Preview',
template: '<button id="preview-code" class="e-tbar-btn e-control e-btn e-icon-btn" aria-label="Preview Code" >' +
'<span class="e-btn-icon e-md-preview e-icons"></span></button>'
}, '|', 'Undo', 'Redo'];
let textArea: HTMLTextAreaElement;
let mdsource: HTMLElement;
const emailData: { [key: string]: string; }[] = [
{ name: "Selma Rose", initial: 'SR', email: "[email protected]", color: '#FAFDFF', bgColor: '#01579B' },
{ name: "Maria", initial: 'MA', email: "[email protected]", color: '#004378', bgColor: '#ADDBFF' },
{ name: "Russo Kay", initial: 'RK', email: "[email protected]", color: '#F9DEDC', bgColor: '#8C1D18' },
{ name: "Robert", initial: 'RO', email: "[email protected]", color: '#FFD6F7', bgColor: '#37003A' },
{ name: "Camden Kate", initial: 'CK', email: "[email protected]", color: '#FFFFFF', bgColor: '#464ECF' },
{ name: "Garth", initial: 'GA', email: "[email protected]", color: '#FFFFFF', bgColor: '#008861' },
{ name: "Andrew James", initial: 'AJ', email: "[email protected]", color: '#FFFFFF', bgColor: '#53CA17' },
{ name: "Olivia", initial: 'OL', email: "[email protected]", color: '#FFFFFF', bgColor: '#8C1D18' },
{ name: "Sophia", initial: 'SO', email: "[email protected]", color: '#000000', bgColor: '#D0BCFF' },
{ name: "Margaret", initial: 'MA', email: "[email protected]", color: '#000000', bgColor: '#F2B8B5' },
{ name: "Ursula Ann", initial: 'UA', email: "[email protected]", color: '#000000', bgColor: '#47ACFB' },
{ name: "Laura Grace", initial: 'LG', email: "[email protected]", color: '#000000', bgColor: '#FFE088' },
{ name: "Albert", initial: 'AL', email: "[email protected]", color: '#FFFFFF', bgColor: '#00335B' },
{ name: "William", initial: 'WA', email: "[email protected]", color: '#FFFFFF', bgColor: '#163E02' }
];
const toolbarSettings: ToolbarSettingsModel = {
items: items
};
const formatter: MarkdownFormatter = new MarkdownFormatter({ listTags: { 'OL': '1., 2., 3.' } });
function markdownConversion(): void {
if (mdsource.classList.contains('e-active')) {
let id: string = rteObj.getID() + 'html-view';
let htmlPreview: HTMLElement = rteObj.element.querySelector('#' + id);
htmlPreview.innerHTML = Marked((rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
}
}
function fullPreview(): void {
let id: string = rteObj.getID() + 'html-preview';
let htmlPreview: HTMLElement = rteObj.element.querySelector('#' + id);
if (mdsource.classList.contains('e-active')) {
mdsource.classList.remove('e-active');
mdsource.parentElement.title = 'Preview';
textArea.style.display = 'block';
htmlPreview.style.display = 'none';
} else {
mdsource.classList.add('e-active');
if (!htmlPreview) {
htmlPreview = createElement('div', { className: 'e-content e-pre-source' });
htmlPreview.id = id;
textArea.parentNode.appendChild(htmlPreview);
}
textArea.style.display = 'none';
htmlPreview.style.display = 'block';
htmlPreview.innerHTML = Marked((rteObj.contentModule.getEditPanel() as HTMLTextAreaElement).value);
mdsource.parentElement.title = 'Code View';
}
}
function rendereComplete(): void {
textArea = rteObj.contentModule.getEditPanel() as HTMLTextAreaElement;
textArea.addEventListener('keyup', (e: KeyboardEventArgs) => {
markdownConversion();
});
mdsource = document.getElementById('preview-code');
mdsource.addEventListener('click', (e: MouseEvent) => {
fullPreview();
if ((e.currentTarget as HTMLElement).classList.contains('e-active')) {
rteObj.disableToolbarItem(['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo']);
} else {
rteObj.enableToolbarItem(['Bold', 'Italic', 'StrikeThrough', '|',
'Formats', 'OrderedList', 'UnorderedList', '|',
'CreateLink', 'Image', 'CreateTable', 'Undo', 'Redo']);
}
});
}
function itemTemplate(data: any): React.JSX.Element {
return (
<div className="editor-mention-item-template">
<div className="em-header">
<div className="em-avatar" style=>
<div className="em-initial">{data.initial}</div>
</div>
</div>
<div className="em-content">
<div className="em-name">{data.name}</div>
<div className="em-email">{data.email}</div>
</div>
</div>
);
}
function displayTemplate(data: any): React.JSX.Element {
return (
<React.Fragment>
[@{data.name}](mailto:${data.email})
</React.Fragment>
);
}
return (
<div className='control-section' id="rteMarkdown">
<div className="content-wrapper">
<RichTextEditorComponent id="markdownRTE"
ref={(richtexteditor) => { rteObj = richtexteditor }} editorMode='Markdown'
height='250px' value={value} formatter={formatter} created={rendereComplete} toolbarSettings={toolbarSettings} >
<Inject services={[MarkdownEditor, Toolbar, Image, Link, Table]} />
</RichTextEditorComponent>
<MentionComponent id='editorMention' ref={(mention: MentionComponent) => { mention = mention }} dataSource={emailData} displayTemplate={displayTemplate} itemTemplate={itemTemplate} target="#markdownRTE_editable-content" fields= popupWidth='250px' popupHeight='200px' sortOrder='Ascending' allowSpaces={true}></MentionComponent>
</div>
</div>
);
}
export default App;