JSPM

@vabster/editor

0.0.2
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 12
  • Score
    100M100P100Q69865F
  • License ISC

Package Exports

  • @vabster/editor
  • @vabster/editor/styles.css

Readme

@vabster/editor

A lightweight WYSIWYG editor for React built on the native contenteditable API — no heavy dependencies.

Installation

npm install @vabster/editor

Usage

import { Editor, Toolbar } from "@vabster/editor";
import "@vabster/editor/styles.css";

export default function App() {
  return (
    <Editor placeholder="Start writing…">
      <Toolbar />
    </Editor>
  );
}

Components

<Editor>

The root component. Renders a contenteditable region and provides editor context to all children.

Prop Type Default Description
placeholder string "" Placeholder text when empty
children ReactNode Toolbar, BubbleMenu, or custom UI

<Toolbar>

A pre-built toolbar with buttons for marks (bold, italic, underline, strikethrough, code, link), block types (headings, lists, blockquote), alignment, and undo/redo.

<BubbleMenu>

A floating menu that appears when text is selected. Shows mark toggle buttons inline.

<ToolbarButton>

A primitive button styled for use inside a toolbar. Use this to build custom toolbar controls.

import { ToolbarButton, useEditorContext } from "@vabster/editor";

function MyBoldButton() {
  const { exec, activeMark } = useEditorContext();
  return (
    <ToolbarButton
      active={activeMark("bold")}
      onClick={() => exec({ type: "toggleMark", mark: "bold" })}
    >
      B
    </ToolbarButton>
  );
}

Hooks & Context

useEditorContext()

Access the editor state and dispatch commands from any component inside <Editor>.

const {
  snapshot,       // full EditorSnapshot — current marks, block, align, etc.
  exec,           // (command: Command) => void
  can,            // (command: Command) => boolean
  activeMark,     // (mark: Mark) => boolean
  activeBlock,    // (block: Block) => boolean
  activeAlign,    // (align: Align) => boolean
} = useEditorContext();

Commands

Pass a Command object to exec():

exec({ type: "toggleMark", mark: "bold" });
exec({ type: "setBlock", block: "heading1" });
exec({ type: "setAlign", align: "center" });
exec({ type: "insertImage", src: "https://…", alt: "photo" });
exec({ type: "insertFile", url: "https://…", name: "doc.pdf", size: 204800 });
exec({ type: "undo" });
exec({ type: "redo" });

Marks: bold | italic | underline | strike | code | link

Blocks: paragraph | heading1heading6 | bulletList | orderedList | blockquote

Align: left | center | right | justify

Custom Adapter

The editor separates the UI from the editing engine via the EditorAdapter interface. NativeAdapter is the built-in implementation, but you can supply your own (e.g. wrapping ProseMirror or another engine) via EditorProvider:

import { EditorProvider, NativeAdapter } from "@vabster/editor";

const adapter = new NativeAdapter(domElement);

<EditorProvider editor={adapter}>
  {/* your custom UI */}
</EditorProvider>

License

ISC