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;