Loading files

In this section, we are going to provide support for loading files.

We learned about keyboard handling and Open Dialog in more detail in Chapter 2, Building a Markdown Editor.

For the sake of simplicity, instead of redirecting events to Node.js, let's handle loading files via the client side. Follow these steps to do so:

  1. Wrap the MonacoEditor element with an extra div element and the container class name:
return (
<div className="container">
<MonacoEditor
language="markdown"
theme="vs-dark"
value={code}
options={options}
onChange={onChange}
editorDidMount={editorDidMount}
/>
</div>
);
  1. Update the App.css file so that it includes the container styling; we need it to take up the entirety of the window:
.App,
.container {
width: 100%;
height: 100%;
}

Traditionally, the programmatic way of triggering the file dialog is to have a hidden input type=file element that includes all the necessary settings and then invoke its click event.

  1. In React, we need to have a reference to the input element, so let's define the fileInputRef constant. Update the Editor.js file and insert the fileInputRef constant at the bottom of the body:
import React, { useState, useRef } from 'react';

const Editor = () => {
const [code, setCode] = useState('# hello world');
const fileInputRef = useRef();

// ...
}
  1. Next, we need a hidden input element of the file type that accepts only text/markdown types. The input element should also be wired to the fileInputRef constant so that we can trigger its methods from the code. In the return block, place the input element as follows:
<div className="container">
<input
ref={fileInputRef}
type="file"
style={{ display: 'none' }}
accept="text/markdown"
onChange={onFileOpened}
></input>

<MonacoEditor ... />
</div>

As you can see, the input element also requires the onFileOpened handler.

  1. Add the following implementation for the onFileOpened function:
const onFileOpened = event => {
if (event.target.files && event.target.files.length > 0) {
const firstFile = event.target.files[0];

const fileReader = new FileReader();
fileReader.onload = e => setCode(e.target.result);
fileReader.readAsText(firstFile);

event.target.value = null;
}
};

The code is pretty self-explanatory. We take the first file and use the FileReader API to get its content as text. As soon as the file's content has been loaded, we call the setCode hook to update the state of the code.

We also have the code hook, which is bound to the MonacoEditor.value property. This means that as soon as we set the value via the setCode hook, the Monaco Editor gets these changes and updates itself.

  1. The last piece of the puzzle is to wire Cmd + O (or Ctrl + O) with the dialog. Update the editorDidMount implementation to invoke click, as shown in the following code:
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KEY_O, () => {
fileInputRef.current.click();
});

That's all you need to do to load a file and run it. Now, let's test the implementation:

  1. Start the web application with the npm start command.
  2. Press Cmd + O if you're using macOS; otherwise, press Ctrl + O.
  3. In the resulting dialog, select a markdown file.
I have saved an example from the Monaco Editor demo (https://microsoft.github.io/monaco-editor/). You can find any markdown file on GitHub, such as a README.md file, and save it locally.
  1. Ensure that the editor loads and displays the file correctly:

Next, let's implement the handler for Cmd + S and add support so that we can save files.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
52.14.224.197