JSFiddle - React, Tailwind, and code Playground

by der_robert

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tinymce/6.4.2/skins/content/default/content.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/tinymce/6.4.2/tinymce.min.js"></script>
<textarea></textarea>

JavaScript

tinymce.init({
  selector: 'textarea',
  height: 500,
  toolbar: 'platzhalter',

  setup: (editor) => {

    const menuItems = [
      {
        text: 'Menu item 1',
        value: '@{x1}',
        onAction: () => editor.insertContent('<span contenteditable="false">@{x1}</span>')
      },
      {
        text: 'Menu item 2',
        value: '@{x2}',
        onAction: () => editor.insertContent('<span contenteditable="false">@{x2}</span>')
      },
      {
        text: 'Menu item 3',
        value: '@{x3}',
        onAction: () => editor.insertContent('<span contenteditable="false">@{x3}</span>')
      },
      {
        text: 'Menu item 4',
        value: '@{x4}',
        onAction: () => editor.insertContent('<span contenteditable="false">@{x4}</span>')
      },
      {
        text: 'Menu item 5',
        value: '@{x5}',
        onAction: () => editor.insertContent('<span contenteditable="false">@{x5}</span>')
      }
    ];

    editor.ui.registry.addMenuButton('platzhalter', {
      text: 'Platzhalter',
      search: {
        placeholder: 'Suche...'
      },
      fetch: (callback, fetchContext) => {
        if (fetchContext.pattern.length > 0) {
          const filteredItems = menuItems.filter(item => {
            return item.text.toLowerCase().indexOf(fetchContext.pattern.toLowerCase()) !== -1;
          }).map(item => {
            return {
              type: 'menuitem',
              text: item.text,
              onAction: () => editor.insertContent('<span contenteditable="false">'+item.value+'</span>')
            };
          });
          if (filteredItems.length > 0) {
            callback(filteredItems);
          } else {
            callback([{
              type: 'menuitem',
              text: 'No search results found.',
              disabled: true
            }]);
          }
        } else {
          const items = menuItems.map(item => {
            return {
              type: 'menuitem',
              text: item.text,
             ...