JSFiddle - React, Tailwind, and code Playground

by Froala_marketing

HTML

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/froala-editor@5/css/froala_editor.pkgd.min.css" />
  



<div id="editor-container">
  <div id="froala-editor">
    <p>Type <strong>/</strong> at the start of a new line to open the command menu.</p>
  </div>
</div>

<!-- The slash command dropdown -->
<div id="slash-menu"></div>

<script src="https://cdn.jsdelivr.net/npm/froala-editor@5/js/froala_editor.pkgd.min.js"></script>

CSS

/* ─── Slash Command Menu Styles ─────────────────────────────── */
    #slash-menu {
      position: absolute;
      z-index: 9999;
      background: #ffffff;
      border: 1px solid #e2e8f0;
      border-radius: 8px;
      box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
      width: 260px;
      max-height: 320px;
      overflow-y: auto;
      display: none; /* Hidden by default */
      font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
    }

    #slash-menu .slash-menu-header {
      padding: 8px 12px 4px;
      font-size: 11px;
      font-weight: 600;
      color: #94a3b8;
      text-transform: uppercase;
      letter-spacing: 0.06em;
    }

    #slash-menu .slash-menu-item {
      display: flex;
      align-items: center;
      gap: 10px;
      padding: 8px 12px;
      cursor: pointer;
      transition: background 0.1s ease;
    }

    #slash-menu .slash-menu-item:hover,
    #slash-menu .slash-menu-item.is-active {
      background: #f1f5f9;
    }

    #slash-menu .slash-menu-item .item-icon {
      width: 32px;
      height: 32px;
      border-radius: 6px;
      background: #f8fafc;
      border: 1px solid #e2e8f0;
      display: flex;
      align-items: center;
      justify-content: center;
      font-size: 15px;
      flex-shrink: 0;
    }

    #slash-menu .slash-menu-item .item-text .item-title {
      font-size: 13px;
      font-weight: 500;
      color: #1e293b;
      line-height: 1.3;
    }

    #slash-menu .slash-menu-item .item-text .item-description {
      font-size: 11px;
      color: #94a3b8;
      line-height: 1.3;
    }

    /* Editor wrapper */
    #editor-container {
      max-width: 800px;
      margin: 40px auto;
      padding: 0 20px;
    }

JavaScript

(function () {
  'use strict';

  // ─── 1. Define the menu items ──────────────────────────────────────────────
  // Each item has: a label, description, icon, category, and an `action`
  // function that receives the editor instance and performs the insertion.
  const SLASH_COMMANDS = [
    {
      category: 'Text',
      items: [
        {
          id: 'paragraph',
          title: 'Text',
          description: 'Plain paragraph',
          icon: '¶',
          action: function (editor) {
            // Insert a plain paragraph and place cursor inside it
            editor.html.insert('<p>​</p>'); // zero-width space keeps the <p> alive
          }
        },
        {
          id: 'h1',
          title: 'Heading 1',
          description: 'Large section heading',
          icon: 'H1',
          action: function (editor) {
            editor.html.insert('<h1>​</h1>');
          }
        },
        {
          id: 'h2',
          title: 'Heading 2',
          description: 'Medium section heading',
          icon: 'H2',
          action: function (editor) {
            editor.html.insert('<h2>​</h2>');
          }
        },
        {
          id: 'h3',
          title: 'Heading 3',
          description: 'Small section heading',
          icon: 'H3',
          action: function (editor) {
            editor.html.insert('<h3>​</h3>');
          }
        },
      ]
    },
    {
      category: 'Lists',
      items: [
        {
          id: 'ul',
          title: 'Bullet List',
          description: 'Unordered list',
          icon: '•',
          action: function (editor) {
            editor.html.insert('<ul><li>​</li></ul>');
          }
        },
        {
          id: 'ol',
          title: 'Numbered List',
          description: 'Ordered list',
          icon: '1.',
          action: function (editor) {
            editor.html.insert('<ol><li>​</li></ol>');
          }
        },
 ...