ProseMirror Plugins
@citolab/prose-extensions provides generic editor behavior that sits alongside @citolab/prose-qti. Use it when you need block selection, node attribute synchronization, or semantic paste cleanup that does not depend on QTI semantics.
Available plugins
- Block Select - block node selection and drag handles
- Node Attrs Sync - keeps node attributes in sync with the DOM
- Semantic Paste - normalizes pasted HTML into semantic structure
Install
pnpm add @citolab/prose-extensionsUsage
Each feature lives under its own subpath export. These subpaths only ever export plain ProseMirror plugins, so @citolab/prose-extensions works without ProseKit installed:
import { blockSelectPlugin } from '@citolab/prose-extensions/block-select';import { nodeAttrsSyncPlugin } from '@citolab/prose-extensions/node-attrs-sync';import { createSemanticPastePlugin } from '@citolab/prose-extensions/paste-semantic-html';If your app is built on ProseKit, import the extension wrappers from @citolab/prose-extensions/prosekit-extensions instead. Importing from this subpath requires the prosekit peer dependency to be installed — it is optional everywhere else in the package:
import { blockSelectExtension, nodeAttrsSyncExtension, defineSemanticPasteExtension,} from '@citolab/prose-extensions/prosekit-extensions';See each plugin’s page for the exact shape of its plugin factory and, where available, its ProseKit extension.
The schema-version compatibility/migration pipeline and local-storage doc
persistence used to be documented here, but they now live inside
apps/qti-prosekit-app (not published) since only that app persists raw
ProseMirror JSON. The virtual cursor plugin was removed — it had no
consumers.
ProseKit marks and lists
@citolab/prose-extensions/prosekit publishes standalone ProseKit wrappers for basic rich-text marks and lists, for apps that don’t already define them. Importing this subpath requires the prosekit peer dependency:
import { defineStrong, defineEm, defineList } from '@citolab/prose-extensions/prosekit';defineStrong()/defineEm()— mark specs reusingprosemirror-schema-basic’sstrong/em(so document JSON stays compatible with that schema), plus atoggleStrong/toggleEmcommand andMod-b/Mod-ikeymap binding.defineList(options?: ListOptions)—bullet_list/ordered_list/list_itemnode specs reusingprosemirror-schema-list’s parse/toDOM, atoggleBulletList/toggleOrderedListcommand pair, and a keymap (Entersplits the current item;Backspaceis restored to ProseMirror’s standard join/lift chain). Pass{ inputRules: true }to enable markdown-style-/1.input rules.
When to use this
Use these helpers when you need editor behavior that is independent of QTI semantics. QTI-specific integration surfaces live in @citolab/prose-qti.