uiwjs / react-codemirror

CodeMirror 6 component for React. @codemirror https://uiwjs.github.io/react-codemirror/
https://uiwjs.github.io/react-codemirror/
MIT License
1.65k stars 132 forks source link

How to programmatically wire up a button to invoke `undo` and `redo`? #365

Closed LyDawei closed 2 years ago

LyDawei commented 2 years ago

Hi, my team is currently using this library and we have a requirement to invoke the undo and redo method in codemirror programmatically. How would I achieve that with this library? It doesn't look like an API is exposed for me to invoke such a command.

Edit: --------------------------------------------------------------------------------------------------------------------- I have dug through lots of forums and articles but can't seem to find a solution that is elegant.

Thank you

jaywcjlove commented 2 years ago

@LyDawei Example: https://codesandbox.io/embed/react-codemirror-example-codemirror-6-uiwjs-react-codemirror-issues-365-hx036r?fontsize=14&hidenavigation=1&theme=dark

import React, { useRef } from "react";
import CodeMirror from "@uiw/react-codemirror";
import { javascript } from "@codemirror/lang-javascript";
import { undo, redo } from "@codemirror/commands";

export default function App() {
  const $ref = useRef();
  const onChange = React.useCallback((value, viewUpdate) => {
    console.log("value:", value);
  }, []);
  const undoHandle = () => {
    if ($ref.current) {
      undo($ref.current.view);
    }
  };
  const redoHandle = () => {
    if ($ref.current) {
      redo($ref.current.view);
    }
  };
  return (
    <div>
      <button onClick={undoHandle}>undo</button>
      <button onClick={redoHandle}>redo</button>
      <CodeMirror
        ref={$ref}
        value="console.log('hello world!');"
        height="200px"
        theme="dark"
        extensions={[javascript({ jsx: true })]}
        onChange={onChange}
      />
    </div>
  );
}
jaywcjlove commented 2 years ago

https://codemirror.net/examples/split/

import {undo, redo} from "@codemirror/commands"

let otherState = EditorState.create({
  doc: startState.doc,
  extensions: [
    drawSelection(),
    lineNumbers(),
    keymap.of([
      ...defaultKeymap,
      {key: "Mod-z", run: () => undo(mainView)},
      {key: "Mod-y", mac: "Mod-Shift-z", run: () => redo(mainView)}
    ])
  ]
})