aboutsummaryrefslogtreecommitdiff
path: root/src/client/util/ProseMirrorEditorView.tsx
diff options
context:
space:
mode:
authorStanley Yip <33562077+yipstanley@users.noreply.github.com>2020-01-09 18:55:14 -0500
committerGitHub <noreply@github.com>2020-01-09 18:55:14 -0500
commit29a1f1dae11e7208977faf0c17ec80b6bad97223 (patch)
tree46204c2bdaa18cc352868b8d67450f8f2a1a3506 /src/client/util/ProseMirrorEditorView.tsx
parent6a45fd58601a2b03ed234f05b9b0a1b91d25a54d (diff)
parenteec70e08bf5fa5f3a0a4e3b07bdc05777f71d2ef (diff)
Merge pull request #329 from browngraphicslab/textbox_fawn_fix
rich text menu
Diffstat (limited to 'src/client/util/ProseMirrorEditorView.tsx')
-rw-r--r--src/client/util/ProseMirrorEditorView.tsx74
1 files changed, 74 insertions, 0 deletions
diff --git a/src/client/util/ProseMirrorEditorView.tsx b/src/client/util/ProseMirrorEditorView.tsx
new file mode 100644
index 000000000..3e5fd0604
--- /dev/null
+++ b/src/client/util/ProseMirrorEditorView.tsx
@@ -0,0 +1,74 @@
+import React from "react";
+import { EditorView } from "prosemirror-view";
+import { EditorState } from "prosemirror-state";
+
+export interface ProseMirrorEditorViewProps {
+ /* EditorState instance to use. */
+ editorState: EditorState;
+ /* Called when EditorView produces new EditorState. */
+ onEditorState: (editorState: EditorState) => any;
+}
+
+/**
+ * This wraps ProseMirror's EditorView into React component.
+ * This code was found on https://discuss.prosemirror.net/t/using-with-react/904
+ */
+export class ProseMirrorEditorView extends React.Component<ProseMirrorEditorViewProps> {
+
+ private _editorView?: EditorView;
+
+ _createEditorView = (element: HTMLDivElement | null) => {
+ if (element != null) {
+ this._editorView = new EditorView(element, {
+ state: this.props.editorState,
+ dispatchTransaction: this.dispatchTransaction,
+ });
+ }
+ };
+
+ dispatchTransaction = (tx: any) => {
+ // In case EditorView makes any modification to a state we funnel those
+ // modifications up to the parent and apply to the EditorView itself.
+ const editorState = this.props.editorState.apply(tx);
+ if (this._editorView != null) {
+ this._editorView.updateState(editorState);
+ }
+ this.props.onEditorState(editorState);
+ };
+
+ focus() {
+ if (this._editorView) {
+ this._editorView.focus();
+ }
+ }
+
+ componentWillReceiveProps(nextProps: { editorState: EditorState<any>; }) {
+ // In case we receive new EditorState through props — we apply it to the
+ // EditorView instance.
+ if (this._editorView) {
+ if (nextProps.editorState !== this.props.editorState) {
+ this._editorView.updateState(nextProps.editorState);
+ }
+ }
+ }
+
+ componentWillUnmount() {
+ if (this._editorView) {
+ this._editorView.destroy();
+ }
+ }
+
+ shouldComponentUpdate() {
+ // Note that EditorView manages its DOM itself so we'd ratrher don't mess
+ // with it.
+ return false;
+ }
+
+ render() {
+ // Render just an empty div which is then used as a container for an
+ // EditorView instance.
+ return (
+ <div ref={this._createEditorView} />
+ );
+ }
+} \ No newline at end of file