React Text Editor With Syntax Highlighting
Recently I have spent a lot of time on a React and Rails project that is going to incorporate user authentication, Redux, Thunk, a robust back-end, and many other features. I have thoroughly enjoyed this project, however, as a JavaScript and Ruby user, I have grown accustomed to the luxury of quickly and without hesitation spinning up entire applications that can be put on the web just as fast. I had the desire for a fast and fun project like this and where this led was a text editor! Here I will do a brief stroll through some of the interesting features of the build. It’s called codepen. https://github.com/JCGuest/codepen.
For syntax highlighting (and again I wanted to do this quickly) I am using a lightweight package and library called PrismJs/prism. You can design a custom color scheme and decide which languages you want to include on their website. https://prismjs.com/index.html
They generate the JavaScript and CSS files you will need to incorporate in your React app. After importing the Prism class you need to provide two standard HTML elements as per the Prismjs documentation. This is where your text will be rendered.
<pre className="code-output"> <code className={`language-${props.language}`}>{content}</code></pre>
You may notice my props there. That is passed from App.js to the only component CodeEditor.js. In App.js I have a menu for the user to select the language and, using useState(); I update the language and render the CodeEditor.
export default function App() { const [editorLanguage, setEditorLanguage] = useState("javascript");return ( <div className="App"> <h1>React Code Editor</h1><fieldset> <legend>Choose language:</legend><input type="radio" id="javascript" name="language"value="javascript" checked={editorLanguage === "javascript"}onChange={() => setEditorLanguage("javascript")}/>
To pass the text to Prism you call Prism.highlightAll();. I am again using hooks so the entire application can be run without creating any React.Component classes. The hook used here is called useEffect(); it works here because it is called when the provided elements are updated.
useEffect(() => {Prism.highlightAll();}, [props.language, content]);
My application utilizes some tricky CSS that I will not go into here but this is the final result. Here you can see me selecting the different languages for highlighting.
The point of this build was to get a finished product working in a matter of an hour or two and to learn some things along the way. It has done that beautifully and it was a lot of fun.