diff options
author | Stanley Yip <33562077+yipstanley@users.noreply.github.com> | 2020-01-09 18:55:14 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-09 18:55:14 -0500 |
commit | 29a1f1dae11e7208977faf0c17ec80b6bad97223 (patch) | |
tree | 46204c2bdaa18cc352868b8d67450f8f2a1a3506 /src/client/util/ProseMirrorEditorView.tsx | |
parent | 6a45fd58601a2b03ed234f05b9b0a1b91d25a54d (diff) | |
parent | eec70e08bf5fa5f3a0a4e3b07bdc05777f71d2ef (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.tsx | 74 |
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 |