What is y-prosemirror?
The y-prosemirror package is a binding for ProseMirror, a toolkit for building rich-text editors, to Yjs, a high-performance CRDT (Conflict-free Replicated Data Type) for building collaborative applications. This package allows you to create collaborative rich-text editors that can be used in real-time by multiple users.
What are y-prosemirror's main functionalities?
Collaborative Editing
This code sets up a ProseMirror editor with Yjs bindings, enabling collaborative editing. The ySyncPlugin synchronizes the editor state with a Yjs document, yCursorPlugin shows the cursor positions of other users, and yUndoPlugin adds undo/redo functionality.
const Y = require('yjs');
const { ySyncPlugin, yCursorPlugin, yUndoPlugin, undo, redo } = require('y-prosemirror');
const { EditorState } = require('prosemirror-state');
const { EditorView } = require('prosemirror-view');
const { schema } = require('prosemirror-schema-basic');
const ydoc = new Y.Doc();
const yXmlFragment = ydoc.getXmlFragment('prosemirror');
const state = EditorState.create({
schema,
plugins: [
ySyncPlugin(yXmlFragment),
yCursorPlugin(ydoc),
yUndoPlugin()
]
});
const view = new EditorView(document.querySelector('#editor'), {
state
});
Undo/Redo Functionality
This code demonstrates how to use the undo and redo functions provided by y-prosemirror to manage undo/redo actions in a collaborative editor.
const { undo, redo } = require('y-prosemirror');
// To undo the last change
undo(view.state, view.dispatch);
// To redo the last undone change
redo(view.state, view.dispatch);
Cursor Synchronization
This code sets up cursor synchronization in a collaborative ProseMirror editor using the yCursorPlugin. It shows the cursor positions of other users in real-time.
const { yCursorPlugin } = require('y-prosemirror');
const ydoc = new Y.Doc();
const yXmlFragment = ydoc.getXmlFragment('prosemirror');
const state = EditorState.create({
schema,
plugins: [
ySyncPlugin(yXmlFragment),
yCursorPlugin(ydoc)
]
});
const view = new EditorView(document.querySelector('#editor'), {
state
});
Other packages similar to y-prosemirror
tiptap
Tiptap is a headless, framework-agnostic, and collaborative editor built on top of ProseMirror. It provides a more modern and flexible API compared to y-prosemirror and includes built-in support for collaborative editing using Yjs.
quill
Quill is a powerful, rich text editor that offers a variety of features for building collaborative applications. While it does not natively support Yjs, it can be integrated with Yjs for collaborative editing, similar to y-prosemirror.
slate
Slate is a completely customizable framework for building rich text editors. It provides a more flexible and extensible API compared to ProseMirror. Like Quill, it can be integrated with Yjs for collaborative editing.
y-prosemirror
ProseMirror Binding for Yjs - Demo
This binding maps a Y.XmlFragment to the ProseMirror state.
Features
- Sync ProseMirror state
- Shared Cursors
- Shared Undo / Redo (each client has its own undo-/redo-history)
- Successfully recovers when concurrents edit result in an invalid document schema
Example
import { ySyncPlugin, yCursorPlugin, yUndoPlugin, undo, redo } from 'y-prosemirror'
import { exampleSetup } from 'prosemirror-example-setup'
import { keymap } from 'prosemirror-keymap'
..
const type = ydocument.get('prosemirror', Y.XmlFragment)
const prosemirrorView = new EditorView(document.querySelector('#editor'), {
state: EditorState.create({
schema,
plugins: [
ySyncPlugin(type),
yCursorPlugin(provider.awareness),
yUndoPlugin(),
keymap({
'Mod-z': undo,
'Mod-y': redo,
'Mod-Shift-z': redo
})
].concat(exampleSetup({ schema }))
})
})
Also look here for a working example.
License
The MIT License © Kevin Jahns