YjsExtension
Summary
The YJS extension is the recommended extension for creating a collaborative editor.
Usage
Installation
This extension is NOT installed for you when you install the main remirror package but need to be installed separately:
You can use the imports in the following way:
import { YjsExtension } from '@remirror/extension-yjs';
The yjs extension provides support for "undo"/"redo" commands, which conflicts with the default history extension. The history extension provides "undo"/"redo" for the changes done by the current user only, while the yjs extension provides "undo"/"redo" on the level of the underlying yjs transactions, which covers changes by all active users. Note however that a yjs "undo" replaces the complete document, which prevents other extensions (such as the annotations extension) from tracking positions.
You can select the yjs "undo"/"redo" implementation by disabling the history extension in the core preset configuration:
const { manager } = useRemirror({
  extensions: () => [new YjsExtension({ getProvider })],
  core: {
    excludeExtensions: ['history'],
  },
});
Alternatively you can also disable the "undo"/"redo" functionality of the yjs extension:
const { manager } = useRemirror({
  extensions: () => [new YjsExtension({ getProvider, disableUndo: true })],
});
Note that using the history extension "undo"/"redo" requires additional support from the y-prosemirror library.
Examples
Source code
import 'remirror/styles/all.css';
import React from 'react';
import { AnnotationExtension, PlaceholderExtension } from 'remirror/extensions';
import { WebrtcProvider } from 'y-webrtc';
import * as Y from 'yjs';
import { YjsExtension } from '@remirror/extension-yjs';
import {
  Remirror,
  ThemeProvider,
  useCommands,
  useCurrentSelection,
  useHelpers,
  useRemirror,
} from '@remirror/react';
const ydoc = new Y.Doc();
// clients connected to the same room-name share document updates
const provider = new WebrtcProvider('remirror-yjs-demo', ydoc);
const extensions = () => [
  new AnnotationExtension(),
  new PlaceholderExtension({ placeholder: 'Open second tab and start to type...' }),
  new YjsExtension({ getProvider: () => provider }),
];
const Menu = () => {
  const { removeAnnotations, addAnnotation, redrawAnnotations } = useCommands();
  const { getAnnotationsAt, selectionHasAnnotation } = useHelpers();
  const selection = useCurrentSelection();
  return (
    <>
      <button
        onClick={() => {
          addAnnotation({ id: `${Date.now()}` });
          focus();
        }}
        disabled={selection.empty}
      >
        Add annotation
      </button>
      <button
        onClick={() => {
          const annotations = getAnnotationsAt(selection.from);
          removeAnnotations(annotations.map(({ id }) => id));
          focus();
        }}
        disabled={!selectionHasAnnotation()}
      >
        Remove annotation(s)
      </button>
      <button
        onClick={() => {
          redrawAnnotations();
          focus();
        }}
      >
        Redraw annotation(s)
      </button>
    </>
  );
};
const Basic = (): JSX.Element => {
  const { manager } = useRemirror({ extensions, core: { excludeExtensions: ['history'] } });
  return (
    <ThemeProvider>
      <Remirror manager={manager} autoFocus autoRender='end'>
        <Menu />
      </Remirror>
    </ThemeProvider>
  );
};
export default Basic;