@sinhala-typer/typing-engine-tiptap
v0.1.0
Published
Tiptap/ProseMirror adapter for @sinhala-typer/typing-engine — binds Edit descriptors to a rich-text ProseMirror document via transactions, block-scoped resync, undo/redo delegated to Tiptap's own history.
Downloads
12
Maintainers
Readme
@sinhala-typer/typing-engine-tiptap
The Tiptap/ProseMirror adapter for
@sinhala-typer/typing-engine
— the rich-text counterpart to
@sinhala-typer/typing-engine-dom.
Binds the engine's host-agnostic Edit descriptors to a ProseMirror document
via real transactions (tr.delete + tr.insertText), not DOM splicing — so
newly typed Sinhala text inherits the caret's active marks (bold, etc.) for
free, and undo/redo is delegated entirely to Tiptap's own history rather than
the engine's generic UndoStack.
The one genuinely new problem this package solves: InputMethod.resync()
and type()/backspace() only ever need "the plain text immediately before
the caret," and Sinhala composition never spans a block boundary — so the
text/offset handed to the engine are always the current block node's plain
text and offset, never the whole document.
Install
@sinhala-typer/typing-engine, @tiptap/core, and @tiptap/pm are peer
dependencies, not bundled:
npm install @sinhala-typer/typing-engine @sinhala-typer/typing-engine-tiptap @tiptap/core @tiptap/pm(typing-engine is a peer dependency for the same reason as in
typing-engine-dom — it exports a module-level language registry, and a
peer dependency guarantees your app and this adapter share the exact same
instance of it. @tiptap/core/@tiptap/pm are peers because your app
already has its own Tiptap installation this adapter must plug into, not
bundle a second copy of.)
Usage
import { getLanguage } from "@sinhala-typer/typing-engine";
import { createSinhalaInputExtension } from "@sinhala-typer/typing-engine-tiptap";
import { useEditor } from "@tiptap/react";
import StarterKit from "@tiptap/starter-kit";
const sinhala = getLanguage("si")!;
const phonetic = sinhala.inputMethods.find((m) => m.id === "phonetic")!;
const { extension, controller } = createSinhalaInputExtension(phonetic);
const editor = useEditor({
// The Sinhala extension must come before StarterKit so its plugin gets
// first refusal on a keystroke, ahead of Tiptap's own compiled keymap.
extensions: [extension, StarterKit],
});
// Later, e.g. from a keyboard-mode dropdown:
controller.setInputMethod(wijesekara);
controller.setEnabled(false); // plain-English passthrough typing
controller.applyExternalEdit(edit); // e.g. a diffed voice-typing resultSee
apps/web/src/components/tiptap-templates/simple/simple-editor.tsx
in the main repo for a complete integration, including voice typing and
autosave.
API
createSinhalaInputExtension(initialMethod) returns
{ extension, controller }:
extension— a TiptapExtension; pass it in yourextensionsarray (before any extension that binds its own Backspace/keymap handling).controller— aSinhalaInputController:setInputMethod(method)— swap input methods; resyncs composition state from the current block.setEnabled(enabled)/isEnabled()— toggle composition on/off entirely (plain passthrough typing when off).applyExternalEdit(edit)— apply an edit that didn't come from a keystroke this plugin handled itself (e.g. a diffed result from@sinhala-typer/voice-typing).
License
MIT
