Notion-Like Vanilla JS WYSIWYG Editor – Redactix

Notion-Like Vanilla JS WYSIWYG Editor – Redactix
Notion-Like Vanilla JS WYSIWYG Editor – Redactix
Redactix is a dependency-free WYSIWYG editor JavaScript library that adds a Notion-style block editing experience to your web page.

It attaches to any textarea field and works with any backend stack that can read a standard form POST.

Features

  • Type / anywhere in the editor to open a command palette.
  • Displays a Floating Editor Toolbar on text selection.
  • A hover handle on each block lets you reorder content by dragging. Touch devices support long-press to drag.
  • Supports Markdown syntax like #, ##, ###, -, *, 1., >, !, or ---.
  • Supports drag-and-drop image upload, clipboard paste, gallery browsing, base64 auto-upload, and per-image attribute editing.
  • Insert and manage tables with row and column controls via a context menu.
  • Themeable via CSS Variables.
  • Supports 20+ languages with automatic RTL detection for Arabic and Hebrew.
  • Pasted content is sanitized on input. Dangerous tags, inline event handlers, javascript: URLs, and unlisted CSS classes are stripped.
  • A built-in search panel with match navigation and replace functionality.
  • Unlimited Undo/Redo history
  • Fullscreen Mode with a single toggle.
  • Real-time Word/Character Counter displayed in the editor footer.
  • Switch to raw HTML editing with syntax highlighting at any time.

How To Use It:

1. Add the stylesheet and import the main class in a type="module" script block:

<!-- Load the editor styles -->
<link rel="stylesheet" href="/redactix/Redactix.css">

<script type="module">
// Import the Redactix class as an ES module
import Redactix from '/redactix/Redactix.js';
// Initialize on all textareas matching the selector
new Redactix({
selector: '.article-editor'
});
</script>

2. Redactix replaces any textarea matching the selector. Pre-populate it with HTML content if needed:

<!-- Redactix attaches to this element and replaces it with the editor UI -->
<textarea class="article-editor">
  <h1>Getting Started</h1>
  <p>Your initial content goes here.</p>
</textarea>

3. The package includes a ready-made PHP script (redactix_images.php) for upload, browse, and delete operations. Point the editor at it with two options:

The upload endpoint expects a multipart POST and returns a JSON object with success, src, srcset, alt, title, and caption. The browse endpoint returns a JSON array of image objects. The delete endpoint accepts action=delete&file=filename.jpg and returns a success flag.

For local development, swap in redactix_images_demo.php. It returns a placeholder image on every upload so you can test the full gallery flow.

new Redactix({
  selector: '.article-editor',
  // POST endpoint for new file uploads
  uploadUrl: '/redactix_images.php',    
  // POST endpoint for gallery browsing
  browseUrl: '/redactix_images.php',    
  // Enables delete buttons in the gallery UI
  allowImageDelete: true               
});

4. For comment forms or user-generated content areas, enable lite mode. Upload features are off and links get automatic nofollow:

new Redactix({
  selector: '.comment-box',
  liteMode: true
});

5. All configuration options.

  • selector (string): CSS selector targeting the textarea elements to initialize. Required.
  • locale (string): Language code for UI text. Defaults to 'en'. Accepts any of the 20+ supported codes ('fr', 'de', 'ru', 'ar', 'he', etc.). RTL is detected automatically from the locale.
  • uploadUrl (string): URL of the server endpoint that handles image file uploads via multipart POST.
  • browseUrl (string): URL of the server endpoint that returns the list of previously uploaded images.
  • allowImageDelete (boolean): Shows delete buttons in the image gallery. Defaults to false.
  • maxHeight (string): Sets a CSS max-height on the editor content area. Accepts any valid CSS length value such as '500px'. The sticky toolbar behavior is disabled when this option is set.
  • classes (array): Array of CSS class strings available for quick selection in the element Attributes dialog.
  • liteMode (boolean): Activates the stripped-down editor mode suited to comment forms and forums. Defaults to false.
  • theme (string): Applies a theme class at initialization. Accepts 'light', 'dark', or 'auto'.
  • calloutPresets (array): Array of objects defining custom callout (aside) styles. Each object takes name, label, and class keys.
  • quotePresets (array): Array of objects defining custom blockquote styles. Each object takes name, label, and class keys.

6. API methods.

const textarea = document.querySelector('#main-editor');

// Returns the editor's current HTML as a clean string.
// Editor-internal wrapper elements are stripped from the output.
const html = textarea.redactix.getContent();

// Replaces all editor content with new HTML.
// This re-initializes all block elements and resets the undo/redo stack.
textarea.redactix.setContent('<h2>Updated Section</h2><p>New body copy here.</p>');

// Forces an immediate sync of editor content to the underlying textarea value.
// The editor syncs automatically on every change, but this call
// is useful just before programmatic form submission.
textarea.redactix.sync();
console.log(textarea.value); // Logs the current HTML string

// Changes the active theme at runtime.
// Accepts 'light', 'dark', or 'auto'.
textarea.redactix.setTheme('dark');

// Copy content between two editor instances.
// Direct textarea.value assignment does not work with Redactix.
// Use getContent() and setContent() across instances.
const source = document.querySelector('#source-editor');
const target = document.querySelector('#target-editor');
target.redactix.setContent(source.redactix.getContent());

7. Type / at any point in the editor to open the command menu. Navigate with arrow keys and press Enter to insert.

Command Inserts
/h1 Heading 1
/h2 Heading 2
/h3 Heading 3
/quote Blockquote
/callout Callout/aside block
/code Code block
/image Image dialog
/youtube YouTube embed
/table Table
/hr Horizontal rule
/ol Numbered list
/ul Bullet list

8. Keyboard shortcuts.

Shortcut Action
Ctrl+B Bold
Ctrl+I Italic
Ctrl+U Underline
Ctrl+Z Undo
Ctrl+Y Redo
Ctrl+F Find & Replace
Escape Exit fullscreen

9. Override the default CSS variables to create your own editor themes.

/* ================================
 Variables - Light Theme (Default)
 ================================ */
:root {
  /* Primary colors */
  --redactix-primary: #2563eb;
  --redactix-primary-hover: #1d4ed8;
  --redactix-primary-light: #dbeafe;
  --redactix-primary-rgb: 37, 99, 235;

  /* Danger colors */
  --redactix-danger: #dc2626;
  --redactix-danger-hover: #b91c1c;
  --redactix-danger-light: #fef2f2;

  /* Base colors */
  --redactix-border: #e5e7eb;
  --redactix-bg: #ffffff;
  --redactix-bg-secondary: #f9fafb;
  --redactix-bg-hover: #f3f4f6;
  --redactix-bg-active: #e5e7eb;
  --redactix-text: #374151;
  --redactix-text-muted: #6b7280;
  --redactix-text-placeholder: #9ca3af;

  /* UI elements */
  --redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
  --redactix-radius: 6px;
  --redactix-overlay: rgba(0, 0, 0, 0.4);

  /* Content elements */
  --redactix-blockquote-bg: #f8fafc;
  --redactix-code-bg: #f3f4f6;
  --redactix-code-color: #e11d48;
  --redactix-mark-bg: #fef08a;
  --redactix-spoiler-bg: #374151;

  /* Code editor (always dark) */
  --redactix-code-editor-bg: #1e1e1e;
  --redactix-code-editor-gutter: #252526;
  --redactix-code-editor-text: #d4d4d4;
  --redactix-code-editor-line: #858585;
  --redactix-code-editor-selection: #264f78;

  /* Pre blocks */
  --redactix-pre-bg: #1f2937;
  --redactix-pre-text: #e5e7eb;

  /* Floating toolbar (always dark) */
  --redactix-floating-bg: #1f2937;
  --redactix-floating-text: #e5e7eb;
  --redactix-floating-separator: rgba(255, 255, 255, 0.2);

  /* Callouts - these are semantic and usually stay the same */
  --redactix-callout-bg: #f3f4f6;
  --redactix-callout-border: #d1d5db;
  --redactix-callout-text: #374151;

  /* Find highlight */
  --redactix-find-highlight: #fef08a;
  --redactix-find-current: #f97316;

  /* Drag states */
  --redactix-drag-bg: #dbeafe;
  --redactix-dragover-bg: #eff6ff;
}

/* ================================
 Dark Theme
 ================================ */
.redactix-wrapper.redactix-dark {
  /* Primary colors - slightly brighter for dark mode */
  --redactix-primary: #3b82f6;
  --redactix-primary-hover: #60a5fa;
  --redactix-primary-light: #1e3a5f;
  --redactix-primary-rgb: 59, 130, 246;

  /* Danger colors */
  --redactix-danger: #ef4444;
  --redactix-danger-hover: #f87171;
  --redactix-danger-light: #3f1d1d;

  /* Base colors */
  --redactix-border: #374151;
  --redactix-bg: #1f2937;
  --redactix-bg-secondary: #111827;
  --redactix-bg-hover: #374151;
  --redactix-bg-active: #4b5563;
  --redactix-text: #f3f4f6;
  --redactix-text-muted: #9ca3af;
  --redactix-text-placeholder: #6b7280;

  /* UI elements */
  --redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
  --redactix-overlay: rgba(0, 0, 0, 0.6);

  /* Content elements */
  --redactix-blockquote-bg: #111827;
  --redactix-code-bg: #374151;
  --redactix-code-color: #fb7185;
  --redactix-mark-bg: #854d0e;
  --redactix-spoiler-bg: #e5e7eb;

  /* Pre blocks */
  --redactix-pre-bg: #111827;
  --redactix-pre-text: #e5e7eb;

  /* Callouts - darker versions */
  --redactix-callout-bg: #374151;
  --redactix-callout-border: #4b5563;
  --redactix-callout-text: #f3f4f6;

  /* Find highlight */
  --redactix-find-highlight: #854d0e;
  --redactix-find-current: #ea580c;

  /* Drag states */
  --redactix-drag-bg: #1e3a5f;
  --redactix-dragover-bg: #1e3a5f;
}

/* Dark theme via prefers-color-scheme (auto mode) */
@media (prefers-color-scheme: dark) {
  .redactix-wrapper.redactix-auto {
    /* Primary colors */
    --redactix-primary: #3b82f6;
    --redactix-primary-hover: #60a5fa;
    --redactix-primary-light: #1e3a5f;
    --redactix-primary-rgb: 59, 130, 246;

    /* Danger colors */
    --redactix-danger: #ef4444;
    --redactix-danger-hover: #f87171;
    --redactix-danger-light: #3f1d1d;

    /* Base colors */
    --redactix-border: #374151;
    --redactix-bg: #1f2937;
    --redactix-bg-secondary: #111827;
    --redactix-bg-hover: #374151;
    --redactix-bg-active: #4b5563;
    --redactix-text: #f3f4f6;
    --redactix-text-muted: #9ca3af;
    --redactix-text-placeholder: #6b7280;

    /* UI elements */
    --redactix-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    --redactix-overlay: rgba(0, 0, 0, 0.6);

    /* Content elements */
    --redactix-blockquote-bg: #111827;
    --redactix-code-bg: #374151;
    --redactix-code-color: #fb7185;
    --redactix-mark-bg: #854d0e;
    --redactix-spoiler-bg: #e5e7eb;

    /* Pre blocks */
    --redactix-pre-bg: #111827;
    --redactix-pre-text: #e5e7eb;

    /* Callouts */
    --redactix-callout-bg: #374151;
    --redactix-callout-border: #4b5563;
    --redactix-callout-text: #f3f4f6;

    /* Find highlight */
    --redactix-find-highlight: #854d0e;
    --redactix-find-current: #ea580c;

    /* Drag states */
    --redactix-drag-bg: #1e3a5f;
    --redactix-dragover-bg: #1e3a5f;
  }
}

Alternatives:

The post Notion-Like Vanilla JS WYSIWYG Editor – Redactix appeared first on CSS Script.


Discover more from RSS Feeds Cloud

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Discover more from RSS Feeds Cloud

Subscribe now to keep reading and get access to the full archive.

Continue reading