diff --git a/README.md b/README.md index 60a0ed3..ffd6ef2 100644 --- a/README.md +++ b/README.md @@ -155,6 +155,8 @@ Here are the props you can pass to the MystEditor component: - `dictionaryPath` *(default: "/dictionaries")* - Path to a folder with dictionaries. For an example see `public/dictionaries/`. - `backslashLineBreak` *(default: true)* - treat `\` as a line break even when it is at the end of a paragraph/block - `additionalStyles` *(`CSSStylesheet` | `CSSStylesheet[]`)* - extra CSS stylesheets to customize the component +- `syncScroll` *(default: false)* - synchronize scrolling of the editor and preview in `Dual Pane` view mode. + - > NOTE: This only works if you set a height limit on the MyST parent element. ## License diff --git a/src/MystEditor.js b/src/MystEditor.js index a4d5228..d3949c6 100644 --- a/src/MystEditor.js +++ b/src/MystEditor.js @@ -50,7 +50,6 @@ const MystWrapper = styled.div` box-sizing: border-box; height: calc(100% - 60px); width: 100%; - height: calc(100vh - 60px); position: relative; background-color: white; ${(props) => props.fullscreen && "box-sizing:border-box; height: calc(100vh - 60px);"} @@ -126,6 +125,7 @@ const MystEditor = ({ getAvatar = (login) => `https://secure.gravatar.com/avatar/${login}?s=30&d=identicon`, backslashLineBreak = true, parent, + syncScroll = false, }) => { const [mode, setMode] = useState(initialMode); const [fullscreen, setFullscreen] = useState(false); @@ -196,6 +196,7 @@ const MystEditor = ({ root: parent, highlights: transforms, preview, + syncScroll, collaboration: { opts: collaboration, setUsers, diff --git a/src/components/CodeMirror.js b/src/components/CodeMirror.js index d278922..31143ab 100644 --- a/src/components/CodeMirror.js +++ b/src/components/CodeMirror.js @@ -163,7 +163,7 @@ const setEditorText = (editor, text) => { }); }; -const CodeMirror = ({ text, id, root, mode, spellcheckOpts, highlights, collaboration, preview }) => { +const CodeMirror = ({ text, id, root, mode, spellcheckOpts, highlights, collaboration, preview, syncScroll }) => { const editorRef = useRef(null); const editorMountpoint = useRef(null); const focusScroll = useRef(null); @@ -219,8 +219,8 @@ const CodeMirror = ({ text, id, root, mode, spellcheckOpts, highlights, collabor .addUpdateListener((update) => update.docChanged && text.set(view.state.doc.toString(), update)) .useFixFoldingScroll(focusScroll) .useMoveCursorAfterFold() - .useSyncPreviewWithCursor({ lineMap: text.lineMap, preview }) .useCursorIndicator({ lineMap: text.lineMap, preview }) + .if(syncScroll, (b) => b.useSyncPreviewWithCursor({ lineMap: text.lineMap, preview })) .create(), }); @@ -231,7 +231,9 @@ const CodeMirror = ({ text, id, root, mode, spellcheckOpts, highlights, collabor editorRef.current = view; window.myst_editor.main_editor = view; - syncEditorWithPreviewScroll(preview.current, text.lineMap, view); + if (syncScroll) { + syncEditorWithPreviewScroll(preview.current, text.lineMap, view); + } collaboration.ycomments?.registerCodeMirror(view); collaboration.provider?.watchCollabolators(collaboration.setUsers); diff --git a/src/extensions/index.js b/src/extensions/index.js index 15e3049..1e16c3a 100644 --- a/src/extensions/index.js +++ b/src/extensions/index.js @@ -177,6 +177,15 @@ export class ExtensionBuilder { return this; } + /** @param {(b: ExtensionBuilder) => ExtensionBuilder} extender */ + if(condition, extender) { + if (condition) { + return extender(this); + } else { + return this; + } + } + useMoveCursorAfterFold() { this.base.push( EditorState.transactionFilter.of((tr) => { diff --git a/src/index.html b/src/index.html index 3c0dbe2..3d6524c 100644 --- a/src/index.html +++ b/src/index.html @@ -204,6 +204,7 @@ dict: "en_US", dictionaryPath: "/myst-editor/dictionaries", }, + syncScroll: true, }, document.getElementById("myst"), );