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

@xuhaocan/mstr-html-editor

v1.0.2

Published

A powerful HTML editor supporting both React components and vanilla JavaScript usage

Readme

MstrHtmlEditor

A powerful, flexible HTML WYSIWYG editor that supports both React components and vanilla JavaScript usage.

Features

  • 🎨 Rich text editing with toolbar
  • ⚛️ React component support
  • 🔧 Vanilla JavaScript API for DOM-based usage
  • 🎯 TypeScript support with full type definitions
  • 📦 Lightweight and performant
  • 🔌 Extensible and customizable
  • 🌐 Internationalization support

Installation

npm install @xuhaocan/mstr-html-editor
# or
yarn add @xuhaocan/mstr-html-editor

🎨 Icon Fonts

The package includes workstation-iconfont by default. To use the toolbar icons:

<!-- Include icon font CSS -->
<link rel="stylesheet" href="node_modules/mstr-html-editor/dist/fonts/icons.css">

Or in your JavaScript/TypeScript:

import 'mstr-html-editor/dist/fonts/icons.css';

Custom Icon Fonts: You can replace the default icon font with your own (Font Awesome, Material Icons, etc.). See ICON_FONT_GUIDE.md for detailed instructions.

🚀 Quick Start & Live Examples

View Examples Locally

After installing the package, you can view live examples:

# Navigate to the package directory
cd node_modules/mstr-html-editor

# Start development server
npm run serve

# Or use the combined build + serve command
npm run dev

Then open your browser to:

  • React Example: http://localhost:8080/examples/react-example.html
  • Vanilla JS Example: http://localhost:8080/examples/vanilla-example.html

Direct File Access

You can also directly open the example HTML files in your browser:

  • examples/react-example.html - Full React implementation with color picker
  • examples/vanilla-example.html - Pure JavaScript usage

Usage

React Usage

import React, { useState } from 'react';
import { ReactHtmlEditor } from 'mstr-html-editor';
import 'mstr-html-editor/dist/styles.css';
import 'mstr-html-editor/dist/fonts/icons.css'; // Icon fonts

function MyEditor() {
  const [content, setContent] = useState('<p>Hello World!</p>');

  const handleChange = (newContent) => {
    console.log('Content changed:', newContent);
    setContent(newContent);
  };

  const handleInit = (context) => {
    console.log('Editor initialized:', context);
    // You can access editor API through context
    // context.focus(), context.isEmpty(), etc.
  };

  return (
    <ReactHtmlEditor
      value={content}
      onChange={handleChange}
      onInit={handleInit}
      options={{
        height: 300,
        placeholder: 'Start typing...',
        toolbar: [
          ['style', ['style']],
          ['font', ['bold', 'underline', 'clear']],
          ['color', ['color']],
          ['para', ['ul', 'ol', 'paragraph']],
          ['table', ['table']],
          ['insert', ['link', 'picture']],
          ['view', ['fullscreen', 'codeview']]
        ]
      }}
    />
  );
}

export default MyEditor;

Vanilla JavaScript Usage

Include via Script Tag (UMD)

<!DOCTYPE html>
<html>
<head>
  <!-- Include icon fonts -->
  <link rel="stylesheet" href="node_modules/mstr-html-editor/dist/fonts/icons.css">
  <!-- Include editor styles -->
  <link rel="stylesheet" href="node_modules/mstr-html-editor/dist/styles.css">
  
  <!-- Required dependencies -->
  <script src="node_modules/jquery/dist/jquery.min.js"></script>
  <!-- React is required for color picker functionality -->
  <script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
  <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
  
  <!-- Include editor -->
  <script src="node_modules/mstr-html-editor/dist/mstr-html-editor.min.js"></script>
</head>
<body>
  <textarea id="myEditor"></textarea>

  <script>
    // Create editor instance
    const editor = MstrHtmlEditor.createHtmlEditor('#myEditor', {
      height: 300,
      placeholder: 'Start typing...',
      callbacks: {
        onChange: function(content) {
          console.log('Content changed:', content);
        },
        onInit: function(context) {
          console.log('Editor initialized');
        }
      }
    });

    // Use editor API
    setTimeout(() => {
      editor.code('<p>Set content programmatically</p>');
      editor.focus();
    }, 1000);
  </script>
</body>
</html>
import { createHtmlEditor } from 'mstr-html-editor/dist/vanilla';
import 'mstr-html-editor/dist/styles.css';
import 'mstr-html-editor/dist/fonts/icons.css'; // Icon fonts

// Create editor on an elementom 'mstr-html-editor/dist/vanilla';
import 'mstr-html-editor/dist/styles.css';

// Create editor on an element
const editor = createHtmlEditor('#myEditor', {
  height: 300,
  placeholder: 'Write something...',
  callbacks: {
    onChange: (content) => {
      console.log('Content:', content);
    }
  }
});

// Use the API
editor.code('<p>Hello from vanilla JS!</p>');
editor.focus();

Initialize Multiple Editors

import { createHtmlEditors } from 'mstr-html-editor/dist/vanilla';

// Initialize all textareas with class 'html-editor'
const editors = createHtmlEditors('.html-editor', {
  height: 250,
  placeholder: 'Enter text...'
});

// Each editor in the array has the full API
editors.forEach((editor, index) => {
  console.log(`Editor ${index + 1} initialized`);
});

API Reference

React Component Props

ReactHtmlEditor

| Prop | Type | Default | Description | |------|------|---------|-------------| | value | string | '' | HTML content of the editor | | onChange | (content: string) => void | - | Callback when content changes | | onInit | (context: HtmlEditorContext) => void | - | Callback when editor initializes | | onFocus | (e: any) => void | - | Callback when editor receives focus | | onBlur | (e: any) => void | - | Callback when editor loses focus | | onKeyUp | (e: any) => void | - | Callback on key up | | onKeyDown | (e: any) => void | - | Callback on key down | | onPaste | (e: any) => void | - | Callback on paste | | disabled | boolean | false | Whether editor is disabled | | codeview | boolean | false | Whether to show code view | | className | string | - | Additional CSS class | | options | HtmlEditorOptions | {} | Editor configuration options |

Vanilla JavaScript API

createHtmlEditor(selector, options)

Creates a single editor instance.

Parameters:

  • selector: CSS selector string or HTMLElement
  • options: Configuration object

Returns: VanillaEditorInstance

Editor Instance Methods

interface VanillaEditorInstance {
  // Get or set HTML content
  code(html?: string): string | void;
  
  // Focus the editor
  focus(): void;
  
  // Check if editor is empty
  isEmpty(): boolean;
  
  // Reset editor to initial state
  reset(): void;
  
  // Enable/disable the editor
  enable(): void;
  disable(): void;
  
  // Destroy the editor
  destroy(): void;
  
  // Insert content at cursor
  insertText(text: string): void;
  insertNode(node: Node): void;
}

Configuration Options

interface HtmlEditorOptions {
  height?: number;                    // Editor height in pixels
  placeholder?: string;               // Placeholder text
  lang?: string;                      // Language code (default: 'en-US')
  toolbar?: Array<Array<any>>;       // Toolbar configuration
  callbacks?: {
    onInit?: (context: any) => void;
    onChange?: (content: string) => void;
    onFocus?: (e: any) => void;
    onBlur?: (e: any) => void;
    // ... other callbacks
  };
  codemirror?: {
    theme?: string;
    mode?: string;
    // ... CodeMirror options
  };
  // ... other options
}

Toolbar Configuration

Customize the toolbar by passing a toolbar array in options:

{
  toolbar: [
    ['style', ['style']],                              // Style dropdown
    ['font', ['bold', 'italic', 'underline', 'clear']], // Font styling
    ['fontname', ['fontname']],                        // Font family
    ['fontsize', ['fontsize']],                        // Font size
    ['color', ['color']],                              // Text color
    ['para', ['ul', 'ol', 'paragraph']],              // Paragraph
    ['height', ['height']],                            // Line height
    ['table', ['table']],                              // Table
    ['insert', ['link', 'picture', 'video']],         // Insert
    ['view', ['fullscreen', 'codeview', 'help']]      // View options
  ]
}

Advanced Examples

With TypeScript

import { ReactHtmlEditor, HtmlEditorContext, ReactHtmlEditorProps } from 'mstr-html-editor';

const MyComponent: React.FC = () => {
  const editorRef = React.useRef<HtmlEditorContext | null>(null);

  const handleInit = (context: HtmlEditorContext) => {
    editorRef.current = context;
  };

  const handleButtonClick = () => {
    if (editorRef.current) {
      editorRef.current.insertText('Inserted text!');
      editorRef.current.focus();
    }
  };

  return (
    <>
      <ReactHtmlEditor onInit={handleInit} />
      <button onClick={handleButtonClick}>Insert Text</button>
    </>
  );
};

Custom Styling

/* Override default styles */
.mstr-html-editor {
  border: 2px solid #e0e0e0;
  border-radius: 8px;
}

.mstr-html-editor .note-toolbar {
  background: #f5f5f5;
  border-bottom: 1px solid #e0e0e0;
}

.mstr-html-editor .note-editable {
  font-family: 'Arial', sans-serif;
  font-size: 14px;
  line-height: 1.6;
}

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Dependencies

  • jQuery 3.6+ (included as dependency)
  • React 16.8+ (peer dependency for React usage only)

License

MIT

Contributing

Contributions are welcome! Please read our contributing guidelines before submitting PRs.

Support

For issues and questions, please open an issue on GitHub.