npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

lax-wp-editor

v2.3.5

Published

A modern, feature-rich WordPress-style editor built with React and TipTap

Readme

Lax WP Editor

A modern, feature-rich WordPress-style editor built with React and TipTap. This editor provides a clean, intuitive interface for rich text editing with customizable toolbars and extensive formatting options.

Table of Contents

Recent Updates

v2.0.0 - Latest Release

✨ Export Functionality

  • Added comprehensive export system with support for multiple formats
  • Export your content as Text (.txt), JSON (.json), Markdown (.md), or HTML (.html)
  • New Export tab in the toolbar for quick access to all export options
  • useExport hook for programmatic export functionality

📝 Variable Text Feature

  • Dynamic variable text support for mail merge and templates
  • Insert variables programmatically from your application
  • onEditorReady callback provides insertVariable method
  • Variables display actual values or {{variableName}} placeholders
  • Supports manual typing with {{variableName}} syntax

🎨 Toolbar Enhancements

  • Improved toolbar dropdown with visual icons for each mode
  • Better visual distinction between Professional, Classic, and Hide Toolbar modes
  • Enhanced toolbar tab interface with 5 tabs: Home, Insert, Table, Page, and Export
  • Smoother transitions between toolbar types

🖼️ Custom Image Support

  • Resizable images with drag handles
  • Image alignment (left, center, right)
  • Bubble menu for image options
  • Inline and block image support

Features

  • 🎨 Modern UI: Clean, responsive design with customizable themes
  • 📝 Rich Text Editing: Full-featured WYSIWYG editor with TipTap
  • 🛠️ Flexible Toolbars: Professional and Classic toolbar modes with tabbed interface
  • 📄 Page Management: Multiple page sizes and orientations
  • 📤 Export Options: Export your content as Text, HTML, Markdown, or JSON
  • 📝 Variable Text: Dynamic variables for mail merge and template systems
  • 🖼️ Image Support: Resizable images with alignment and custom styling
  • 🎯 Customizable: Easy to integrate and customize
  • 📱 Responsive: Works seamlessly on desktop and mobile
  • 🔧 TypeScript: Full TypeScript support with type definitions

Installation

npm install lax-wp-editor
# or
yarn add lax-wp-editor
# or
pnpm add lax-wp-editor

Quick Start

import React from 'react';
import { Editor } from 'lax-wp-editor'; // CSS is automatically included!

function App() {
  return (
    <div style={{ height: '100vh', width: '100%' }}>
      <Editor />
    </div>
  );
}

export default App;

✨ New in v1.2.0: CSS is now automatically imported! You no longer need to manually import the styles.

For older versions (v1.1.x), you need to manually import styles:

import 'lax-wp-editor/styles';
// or
import 'lax-wp-editor/dist/lax-wp-editor.css';

Configuration

The editor accepts a config prop with the following options:

Basic Configuration

import { Editor, type EditorConfig } from 'lax-wp-editor';

function App() {
  const config: EditorConfig = {
    // Initial content (HTML string)
    content: '<p>Your initial content here</p>',
    
    // Toolbar type: 'professional' or 'classic'
    defaultToolbar: 'professional',
    
    // Enable/disable features
    showBubbleMenu: true,           // Show bubble menu on text selection
    showFloatingMenu: false,        // Show floating menu on empty lines
    showPageSizeSelector: true,     // Show page size selector
    enablePagination: true,         // Enable pagination
    
    // Content change callback with debounce
    debounceTimeForContentChange: 300,  // Debounce time in milliseconds (default: 300ms)
    onContentChange: (editor) => {
      const html = editor.getHTML();
      console.log('Content changed:', html);
    },
  };

  return (
    <div style={{ height: '100vh', width: '100%' }}>
      <Editor config={config} />
    </div>
  );
}

AI Autocompletion

You can enable AI autocompletion by providing your own completion function:

import { Editor, type EditorConfig } from 'lax-wp-editor';

function App() {
  const config: EditorConfig = {
    aiAutocompletion: {
      enabled: true,
      minWordsToTriggerAutoCompletion: 5, // Trigger after 5 words (default: 3)
      debounceTime: 300, // Wait 300ms before calling API (default: 100ms)
      
      // Required: Provide your custom fetch function
      fetchCompletion: async (text: string) => {
        const response = await fetch('https://your-api.com/completions', {
          method: 'POST',
          headers: { 
            'Content-Type': 'application/json',
            'Authorization': 'Bearer YOUR_API_KEY',
          },
          body: JSON.stringify({ prompt: text }),
        });
        const data = await response.json();
        return data.completion; // Return the completion text
      },
    },
  };

  return (
    <div style={{ height: '100vh', width: '100%' }}>
      <Editor config={config} />
    </div>
  );
}

⚠️ Important: AI autocompletion requires you to provide a fetchCompletion function. The editor does not include a default AI service.

Keyboard Shortcuts for AI Autocompletion:

  • Tab - Accept suggestion
  • Escape - Dismiss suggestion
  • Ctrl+Shift+Space (Windows/Linux) or Cmd+Shift+Space (Mac) - Toggle autocompletion on/off

Export Functionality

The editor includes a comprehensive export system that allows users to download their content in multiple formats:

import { Editor, useExport } from 'lax-wp-editor';

function MyEditorComponent({ editor }) {
  const { 
    downloadTextFile, 
    downloadJsonFile, 
    downloadMarkdownFile, 
    downloadHtmlFile 
  } = useExport(editor);

  return (
    <div>
      <button onClick={downloadTextFile}>Export as Text</button>
      <button onClick={downloadJsonFile}>Export as JSON</button>
      <button onClick={downloadMarkdownFile}>Export as Markdown</button>
      <button onClick={downloadHtmlFile}>Export as HTML</button>
    </div>
  );
}

Available Export Formats:

| Format | Description | Method | |--------|-------------|--------| | Text | Plain text (.txt) | downloadTextFile() | | JSON | TipTap JSON format (.json) | downloadJsonFile() | | Markdown | Markdown format (.md) | downloadMarkdownFile() | | HTML | HTML format (.html) | downloadHtmlFile() |

💡 Tip: The Export tab is built into the toolbar and provides quick access to all export formats. You can also use the useExport hook to create custom export buttons.

Variable Text Feature

The editor supports dynamic variable text that can be inserted programmatically from your application. Variables are displayed as placeholders that get replaced with actual values.

Enable Variable Text:

import { useState } from 'react';
import { Editor } from 'lax-wp-editor';

function App() {
  const [insertVariable, setInsertVariable] = useState<((key: string, value?: string) => void) | null>(null);

  const handleInsertName = () => {
    insertVariable?.('userName');
  };

  const handleInsertEmailWithValue = () => {
    insertVariable?.('email', '[email protected]');
  };

  return (
    <div>
      <button onClick={handleInsertName}>Insert User Name</button>
      <button onClick={handleInsertEmailWithValue}>Insert Email</button>
      
      <Editor 
        config={{
          enableVariableText: true,
          variableValues: {
            userName: 'John Doe',
            email: '[email protected]',
            company: 'Acme Inc',
          },
          onEditorReady: ({ insertVariable: insert }) => {
            // Store the insertVariable method when editor is ready
            setInsertVariable(() => insert);
          },
        }}
      />
    </div>
  );
}

Variable Text Configuration:

| Option | Type | Description | |--------|------|-------------| | enableVariableText | boolean | Enable/disable variable text feature | | variableValues | Record<string, string> | Key-value pairs for variable replacements | | onEditorReady | (methods) => void | Callback that provides editor methods including insertVariable |

Insert Variable Method:

insertVariable(key: string, value?: string)
  • key: The variable name/key
  • value: (Optional) Update the variable value before inserting

How Variables Work:

  1. Variables are inserted as special nodes in the editor
  2. They display the value from variableValues config
  3. If no value exists, they display as {{variableName}}
  4. Variables can be typed manually using {{variableName}} syntax (if enabled)
  5. Users can insert variables programmatically from outside the editor

Example Use Cases:

  • Mail merge functionality
  • Template systems
  • Dynamic content generation
  • Personalized documents

Configuration Options Reference

| Option | Type | Default | Description | |--------|------|---------|-------------| | content | string | "" | Initial HTML content for the editor | | defaultToolbar | 'professional' \| 'classic' | 'professional' | Toolbar style | | showBubbleMenu | boolean | true | Show bubble menu on text selection | | showFloatingMenu | boolean | false | Show floating menu on empty lines | | showPageSizeSelector | boolean | true | Show page size selector | | enablePagination | boolean | true | Enable pagination | | debounceTimeForContentChange | number | 300 | Debounce time (ms) for onContentChange callback | | onContentChange | (editor: Editor) => void | undefined | Callback when content changes (debounced) | | enableVariableText | boolean | false | Enable variable text feature | | variableValues | Record<string, string> | {} | Variable name to value mappings | | onEditorReady | (methods) => void | undefined | Callback with editor methods when ready | | onShare | () => void | undefined | Callback when share button is clicked | | aiAutocompletion | AIAutocompletionConfig | See below | AI autocompletion configuration |

AIAutocompletionConfig:

| Option | Type | Default | Description | |--------|------|---------|-------------| | enabled | boolean | false | Enable/disable AI autocompletion | | minWordsToTriggerAutoCompletion | number | 3 | Minimum words to trigger autocompletion | | debounceTime | number | 100 | Debounce time (ms) before calling API | | fetchCompletion | (text: string) => Promise<string> | undefined | Required - Custom fetch function for AI completions |

Important: Fixing ProseMirror Duplication Error

If you encounter the localsInner error, it's caused by multiple versions of ProseMirror packages in your application's dependency tree.

Official Tiptap Solution:

This package already uses @tiptap/pm for all ProseMirror functionality (as recommended by Tiptap). However, you need to ensure your application also deduplicates ProseMirror versions.

1. In your application directory, check for duplicate ProseMirror versions:

npm ls prosemirror-view
# or
yarn list prosemirror-view

2. If you see multiple versions, add this to YOUR APPLICATION's package.json:

For Yarn users:

{
  "resolutions": {
    "prosemirror-view": "^1.41.0",
    "prosemirror-state": "^1.4.3",
    "prosemirror-model": "^1.25.0",
    "prosemirror-transform": "^1.10.0"
  }
}

For npm users (v8.3.0+):

{
  "overrides": {
    "prosemirror-view": "^1.41.0",
    "prosemirror-state": "^1.4.3",
    "prosemirror-model": "^1.25.0",
    "prosemirror-transform": "^1.10.0"
  }
}

For pnpm users:

{
  "pnpm": {
    "overrides": {
      "prosemirror-view": "^1.41.0",
      "prosemirror-state": "^1.4.3",
      "prosemirror-model": "^1.25.0",
      "prosemirror-transform": "^1.10.0"
    }
  }
}

3. Clean install in YOUR APPLICATION:

# In your application directory (not lax-wp-editor)
rm -rf node_modules package-lock.json  # or yarn.lock / pnpm-lock.yaml
npm install  # or yarn / pnpm install

4. Verify all packages are deduped:

npm ls prosemirror-view
# All instances should show "deduped" and point to the same version

Note: This package uses @tiptap/pm internally (not direct ProseMirror imports) to prevent version conflicts. The deduplication step is only needed if other packages in your project import ProseMirror directly.

Basic Usage

Simple Editor

import { Editor, ToolbarProvider } from 'lax-wp-editor';
import 'lax-wp-editor/styles';

function MyEditor() {
  return (
    <ToolbarProvider>
      <Editor />
    </ToolbarProvider>
  );
}

Custom Configuration

import { Editor, ToolbarProvider, defaultEditorConfig } from 'lax-wp-editor';
import 'lax-wp-editor/styles';

function MyEditor() {
  const config = {
    ...defaultEditorConfig,
    // Add your custom configuration
  };

  return (
    <ToolbarProvider>
      <Editor config={config} />
    </ToolbarProvider>
  );
}

Different Toolbar Types

The editor supports three toolbar modes:

  1. Professional - Multi-row toolbar with all options visible
  2. Classic - Single-row compact toolbar with grouped controls
  3. Hide Toolbar - No toolbar (presentation mode)
import { Editor, ToolbarProvider, TOOLBAR_TYPES_ENUM } from 'lax-wp-editor';
import 'lax-wp-editor/styles';

function MyEditor() {
  return (
    <ToolbarProvider initialToolbar={TOOLBAR_TYPES_ENUM.CLASSIC}>
      <Editor />
    </ToolbarProvider>
  );
}

Users can switch between toolbar modes using the built-in toolbar dropdown menu, which includes icons for each mode:

  • 📊 Classic - Compact view
  • 🎛️ Professional - Full view
  • 👁️ Hide Toolbar - Hidden view

Components

Main Components

  • Editor: The main editor component
  • ToolbarProvider: Context provider for toolbar state
  • Toolbar: Main toolbar component with tabbed interface
  • ProfessionalToolbar: Professional-style toolbar (multi-row layout)
  • ClassicToolbar: Classic-style toolbar (single-row layout)
  • ToolbarDropdown: Dropdown to switch between toolbar modes

Toolbar Tabs

The editor includes a tabbed toolbar interface with the following tabs:

  • Home: Basic formatting options (bold, italic, underline, alignment, etc.)
  • Insert: Insert elements (tables, images, dividers, etc.)
  • Table: Table-specific operations (add/remove rows/columns, merge cells, etc.)
  • Page: Page settings (size, orientation, margins, background)
  • Export: Export content in multiple formats (Text, JSON, Markdown, HTML)

Individual Toolbar Components

  • HeadingOptions: Heading selection dropdown
  • HomeOptions: Basic formatting options
  • FontStyleOptions: Font styling options
  • ParagraphStyleOption: Paragraph styling
  • ExportOptions: Export functionality for multiple file formats
  • TableOptions: Table manipulation controls
  • InsertOptions: Insert various elements into the document

Utility Components

  • SvgIcon: SVG icon component
  • PageSizeSelector: Page size and orientation selector
  • Button: Base button component
  • ColorPicker: Color picker for text and background colors

Hooks

  • useTiptapEditorState: Access editor state
  • useHeadingStyleMethods: Heading manipulation methods
  • useFontStyleMethods: Font styling methods
  • useHomeOptionMethods: Basic formatting methods
  • useParagraphStyleMethods: Paragraph styling methods
  • usePageMethods: Page size and layout management
  • useExport: Export content in multiple formats (Text, JSON, Markdown, HTML)
  • useTableMethods: Table manipulation methods
  • useLinks: Link management methods
  • usePresentationMode: Presentation mode controls
  • useZoom: Zoom controls for the editor

Configuration

Editor Configuration

import { EditorConfig } from 'lax-wp-editor';

const config: EditorConfig = {
  // Your configuration options
};

Toolbar Types

import { TOOLBAR_TYPES_ENUM } from 'lax-wp-editor';

// Available toolbar types:
TOOLBAR_TYPES_ENUM.PROFESSIONAL  // Professional toolbar (multi-row, all options visible)
TOOLBAR_TYPES_ENUM.CLASSIC       // Classic toolbar (single-row, compact)
TOOLBAR_TYPES_ENUM.HIDE_TOOLBAR  // Hide toolbar completely

The toolbar includes 5 tabs:

  • Home: Text formatting, alignment, lists, etc.
  • Insert: Tables, images, dividers, and other insertable elements
  • Table: Table-specific operations (add/remove rows/columns, merge cells)
  • Page: Page layout settings (size, orientation, margins, background)
  • Export: Download content in various formats (Text, JSON, Markdown, HTML)

Styling

The package includes default styles that you can import:

import 'lax-wp-editor/styles';

You can also customize the styles by overriding CSS variables or using your own CSS.

TypeScript Support

The package includes full TypeScript definitions:

import { Editor, EditorConfig, PageSize } from 'lax-wp-editor';

API Reference

Editor Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | config | EditorConfig | defaultEditorConfig | Editor configuration | | onUpdate | (content: string) => void | - | Callback when content changes | | initialContent | string | - | Initial editor content |

ToolbarProvider Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | initialToolbar | ToolbarType | PROFESSIONAL | Initial toolbar type | | children | ReactNode | - | Child components |

ToolbarDropdown Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | onToolbarChange | (toolbarType: string) => void | - | Callback when toolbar type changes |

useExport Hook

Returns an object with the following methods:

| Method | Description | |--------|-------------| | downloadTextFile() | Downloads content as plain text (.txt) | | downloadJsonFile() | Downloads content as TipTap JSON format (.json) | | downloadMarkdownFile() | Downloads content as Markdown (.md) | | downloadHtmlFile() | Downloads content as HTML (.html) |

Examples

Custom Toolbar

import { Editor, Toolbar, HeadingOptions, HomeOptions } from 'lax-wp-editor';

function CustomEditor() {
  return (
    <div>
      <Toolbar>
        <HeadingOptions />
        <HomeOptions />
      </Toolbar>
      <Editor />
    </div>
  );
}

Page Size Management

import { Editor, PageSizeSelector, usePageMethods } from 'lax-wp-editor';

function EditorWithPageSize() {
  const { pageSize, setPageSize } = usePageMethods();
  
  return (
    <div>
      <PageSizeSelector />
      <Editor />
    </div>
  );
}

Export Functionality

import { Editor, useExport } from 'lax-wp-editor';

function EditorWithExport() {
  const editorRef = useRef(null);
  const { 
    downloadTextFile, 
    downloadJsonFile, 
    downloadMarkdownFile, 
    downloadHtmlFile 
  } = useExport(editorRef.current);
  
  return (
    <div>
      <div className="export-buttons">
        <button onClick={downloadTextFile}>Download as Text</button>
        <button onClick={downloadJsonFile}>Download as JSON</button>
        <button onClick={downloadMarkdownFile}>Download as Markdown</button>
        <button onClick={downloadHtmlFile}>Download as HTML</button>
      </div>
      <Editor ref={editorRef} />
    </div>
  );
}

Switching Toolbar Modes

import { Editor, ToolbarProvider, ToolbarDropdown } from 'lax-wp-editor';

function EditorWithToolbarSwitch() {
  return (
    <ToolbarProvider>
      <ToolbarDropdown onToolbarChange={(type) => console.log('Toolbar changed to:', type)} />
      <Editor />
    </ToolbarProvider>
  );
}

Development

Building the Package

npm run build

Running Storybook

npm run storybook

Linting

npm run lint

Keywords

wysiwyg, editor, react, tiptap, wordpress, rich-text, text-editor, markdown, html-editor, document-editor, export, typescript

Contributing

Contributions are welcome! Here's how you can help:

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

Please make sure to:

  • Follow the existing code style
  • Add tests for new features
  • Update documentation as needed
  • Test your changes thoroughly

License

MIT © Rifat Hasan Shaun

Author

Rifat Hasan Shaun

Support

If you have any questions or need help, please: