JSPM

@veztraa/editor

0.1.1
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Score
    100M100P100Q6735F
  • License MIT

Full-featured WYSIWYG rich text editor as a standalone React component — toolbar, source view, HTML sanitizer, dark mode.

Package Exports

  • @veztraa/editor

Readme

@veztraa/editor

Documentation & Live Demo →

A full-featured, zero-config WYSIWYG rich-text editor as a single React component. Drop <Editor /> into any React app and your users get a modern editing experience in seconds — a Notion-style slash menu, a floating selection toolbar, Markdown shortcuts, a full emoji picker, live code-block syntax highlighting, image uploads, and clean semantic HTML out.

TypeScript-first, framework-agnostic (React 18 & 19, Next.js App Router, Vite), dark mode built in. Styles auto-inject on mount — no CSS import required.

Installation

npm install @veztraa/editor

Quick start

import { useState } from "react";
import { Editor } from "@veztraa/editor"; // styles auto-inject — no CSS import

export default function App() {
  const [html, setHtml] = useState("<p>Hello world</p>");
  return <Editor value={html} onChange={setHtml} height={400} />;
}

<EditorModal /> renders in a fullscreen portal and commits changes only when the user clicks Done.

import { EditorModal } from "@veztraa/editor";

{open && (
  <EditorModal
    value={content}
    onChange={(html) => { save(html); setOpen(false); }}
    onClose={() => setOpen(false)}
    title="Edit content"
  />
)}

Features

  • Slash menu — type / for headings, lists, tables, images, code blocks, and more
  • Bubble toolbar — a formatting bar that appears over selected text
  • Markdown shortcuts#, -, 1., >, ```, **bold**, *italic*, `code`, ~~strike~~ format as you type
  • Emoji picker — the full 1,900+ Unicode set in a categorized grid, plus :shortcode: autocomplete
  • Code blocks — live syntax highlighting
  • Autolink — URLs become links as you type
  • URL auto-embed — paste a YouTube/Vimeo link → a responsive, sandboxed embed
  • Images — drag-drop, paste (incl. screenshots), or the toolbar button; inline base64 by default or upload to your server via onImageUpload
  • Tables, text/background color, alignment, indent, sub/superscript, find & replace, print
  • Character limit with a live counter (maxLength)
  • Extensible — add your own slash commands and toolbar buttons
  • Clean output — semantic HTML via onChange, plus a sanitizeHtml() helper
  • Dark & light themes, one-hex accentColor, controlled or uncontrolled

Framework notes

  • Vite / CRA — import and use, nothing extra.
  • Next.js (App Router) — the editor renders on the client. Mark the file "use client", or import it with next/dynamic and { ssr: false }. Importing the package in a server file is safe (it touches no DOM at import time). No CSS import is needed — styles inject on first render.
  • sanitizeHtml() runs in the browser — your editor value already lives client-side, so sanitize there before submitting.

Key props

Prop Type Description
value string HTML content (controlled).
onChange (html: string) => void Fires on every change with the current HTML.
placeholder string Placeholder shown when empty.
height number | string Editor height (px number or any CSS value).
theme "light" | "dark" Controlled color theme.
readOnly boolean Display content without editing.
accentColor string 6-digit hex driving buttons, focus rings, active states.
maxLength number Hard character cap; the counter turns red at the limit.
onImageUpload (file: File) => Promise<string> | string Upload handler for dropped/pasted/picked images; return the hosted URL. Omit to inline as base64.
slashCommands SlashCommand[] Extra entries for the / menu.
toolbarButtons ToolbarButton[] Extra toolbar buttons (icon + action).
onFocus / onBlur () => void Focus / blur of the editing area.
onLinkClick (href, event) => void Link clicks; call event.preventDefault() to handle navigation yourself.
slashMenu / bubbleToolbar / statusBar boolean Toggle the premium UI layers (all default true).
config object Passthrough to the underlying engine options.

EditorProps, EditorModalProps, SlashCommand, and ToolbarButton are all exported.

Recipes

Upload images to your server

<Editor
  value={html}
  onChange={setHtml}
  onImageUpload={async (file) => {
    const body = new FormData();
    body.append("file", file);
    const res = await fetch("/api/upload", { method: "POST", body });
    const { url } = await res.json();
    return url; // inserted as <img src={url}>
  }}
/>

Custom slash commands

<Editor
  value={html}
  onChange={setHtml}
  slashCommands={[
    {
      title: "Callout",
      description: "Highlighted note box",
      action: ({ insertHTML }) =>
        insertHTML("<blockquote>💡 <strong>Note:</strong> …</blockquote>"),
    },
  ]}
/>

Custom toolbar buttons

<Editor
  value={html}
  onChange={setHtml}
  toolbarButtons={[
    {
      name: "insertDate",
      tooltip: "Insert today's date",
      iconSvg: '<svg class="rte-mico" viewBox="0 0 24 24"><rect x="3" y="4" width="18" height="18" rx="2"/><path d="M3 10h18"/></svg>',
      exec: ({ insertText }) => insertText(new Date().toLocaleDateString()),
    },
  ]}
/>

Sanitize before you store

import { sanitizeHtml } from "@veztraa/editor";

const clean = sanitizeHtml(dirtyHtml); // allowlist: safe tags, attrs & styles only

License

MIT © Veztraa Solutions. This package bundles a modified third-party editor engine under its own MIT license; see THIRD-PARTY-NOTICES.txt.