0.0.1-beta.124 • Published 4 years ago

@marduke182/prosemirror-react-view v0.0.1-beta.124

Weekly downloads
13
License
MIT
Repository
-
Last release
4 years ago

ProseMirror React View

This library is a full React implementation of the official prosemirror-view package. Aims to implement a simple React Component that uses ProseMirror Data Model to render the document and bind the right events to synchronize the user selection and created ProseMirror transaction based on user inputs.

TODO

  • Support of decorations
  • Improve selection synchronization to support block nodes and decorations.
  • Add Cypress tests, tried but I was getting a bug of high CPU.

Components

Renderer

Usage

import { Node as ProseMirrorNode } from 'prosemirror-model';
import { Renderer, SchemaDOMSerializer, DecorationSet } from 'prosemirror-react-view';

interface Props {
  node: ProseMirrorNode,
  decorations: DecorationSet,
}

const MyRenderer: React.FC<Props> = ({ doc, decorations }) => {
  return (
    <SchemaDOMSerializer schema={mySchema} plugins={myPlugins}>
    	<Renderer doc={doc} decorations={decorations} />
    </SchemaDOMSerializer>
  )
}

Editor

Usage

import { Editor } from 'prosemirror-react-view';

interface Props {
  onChange(node: ProseMirrorNode): void
}

const MyEditor: React.FC<Props> = ({ onChange }) => {
  return (
    <Editor 
      schema={mySchema} 
      initialDoc={doc} 
      plugins={myPlugins} 
      onChange={onChange}
    />
   )
}

Advance Usage

import {
  Renderer,
  Editor,
  Editable
  DomSerializer,
  DOMSerializerContext,
  useEditorState,
  useEditorView,
} from 'prosemirror-react-view';

class CustomSerializer implements DomSerializer {
  // implement
}

const MyToolbar: React.FC = () => {
  const toolbarState = useEditorState(editorState => editorState.toolbarState);
  const editorView = useEditorView();
  
  return <Toolbar toolbar={toolbarState} editorView={editorView} />;
}

const CustomRenderer: React.FC = () => {
  // Create my custom serializer instance
  const customSerializer = useMemo(() => new CustomSerializer(), []);
  
  // Extract my doc and my decorations from the ProseMirror Editor State
  const doc = useEditorState(editorState => editorState.doc);
  const decorations = useEditorState(editorState => editorState.decorations);

  return (
    <DOMSerializerContext value={customSerializer}>
      <Renderer doc={doc} decorations={decorations} />			
    </DOMSerializerContext>
  );
}

const MyAdvanceEditor: React.FC = () => {
  return (
    <Editor schema={mySchema} plugins={myPlugins}>
    	<MyToolbar />
    	<Editable>
          <CustomRenderer/>
    	</Editable>
    </Editor>
  );
}

Thanks

This project is highly inspired by these two projects:

  • ProseMirror View: The official library to render ProseMirror Editor, it covers a lot of border cases and makes easy to understand the best approach to calculate selection, also contains a lot of the core functionaly that this library needs to implement.
  • Slate: A great project with great ideas. It helped me to understand the best approach to trigger/capture events in React. Most of the logic around synchronize selection and beforeInput strategy were based on this implementations.