Designing a Markdown note taking application in ReactJS
In this article, we will learn how to design a Markdown note-taking application in React that can help one to quickly jot down notes and download the rendered output. The use of Markdown allows one to spend less time on formatting the text and therefore create rich text content using only the Markdown syntax.
Prerequisites:
Steps to Create the React Application And Installing Module:
Step 1: Create a React application using the following command.
npx create-react-app foldername
Step 2: After creating your project folder i.e. foldername, move to it using the following command.
cd foldername
Step 3: Installing necessary modules
npm install markdown-it file-saver
Step 4: Creating a simple User Interface using Bootstrap
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"markdown-it": "^13.0.2",
"web-vitals": "^2.1.4",
}
Example: We can bind these functions with the respective onClick event handlers of the two buttons we have created. Clicking on the buttons will open a Save As dialog on the browser with the given filename and the user can choose to save the file as required.
Javascript
import { useState } from 'react' ; // Import the required modules import MarkdownIt from 'markdown-it' ; import FileSaver from 'file-saver' ; import './App.css' ; function App() { // Create the states that will be used // through the application // This state will be used for the Markdown text let [markdownText, setMarkDownText] = useState( "" ); // This state will be used for the rendered HTML let [renderedHTML, setRenderedHTML] = useState( "" ); // This state will be used for the filename while saving let [fileName, setFileName] = useState( "untitled-note" ); // Create a function that will be invoked // whenever the user modifies the content // in the textarea function handleTextInput(e) { // Change the text of the markdown side setMarkDownText(e.target.value); // Initialize a MarkdownIt instance let md = new MarkdownIt(); // Render out the markdown to HTML using // the render() method let renderedHTML = md.render(e.target.value); // Change the markdown's side to the rendered HTML setRenderedHTML(renderedHTML); } // Create a function download the rendered HTML function saveHTML() { // Create a new Blob of the type 'text/html' // using the rendered HTML content let blobFile = new Blob([renderedHTML], { type: "text/html" }); // Save the file using the given file name FileSaver.saveAs(blobFile, fileName); } // Create a function download the Markdown text function saveMarkdown() { // Create a new Blob of the type 'text' // using the markdown content let blobFile = new Blob([markdownText], { type: "text" }); // Save the file using the given file name FileSaver.saveAs(blobFile, fileName); } return ( <div className= "container" > <h2 className= "app-heading text-center display-4 my-3" > React Markdown Notes </h2> <div className= "row" > <div className= "col col-sm-12 col-md-6" > { /* Card for the markdown editor */ } <div className= "card bg-light markdown-editor" > <h4 className= "card-title text-center" > Markdown </h4> <div className= "card-body" > { /* Textarea for the markdown editor */ } <textarea className= "form-control markdown-textarea" rows={20} value={markdownText} onChange={handleTextInput} ></textarea> </div> </div> </div> <div className= "col col-sm-12 col-md-6" > { /* Card for the markdown editor */ } <div className= "card bg-light rendered-output" > <h4 className= "card-title text-center" > Output </h4> { /* Textarea for the markdown editor */ } <div className= "card-body" > <div // Change the HTML to be displayed according // to the render produced by MarkdownIt dangerouslySetInnerHTML={{ __html: renderedHTML }} className= "rendered-html-output" > </div> </div> </div> </div> </div> <div className= "row" > <div className= "col col-sm-12" > { /* Card for the save files option */ } <div className= "card bg-light my-3" > <div className= "card-body" > <h4>Save Content</h4> <div className= "input-group" > <input type= "text" className= "form-control" placeholder= "File name" aria-label= "File name" value={fileName} onChange={fname => setFileName(fname.target.value)} /> { /* Buttons for saving the text */ } <div className= "input-group-append" > <button className= "btn btn-primary" type= "button" onClick={saveMarkdown}> Save Markdown </button> <button className= "btn btn-primary" type= "button" onClick={saveHTML}> Save HTML </button> </div> </div> </div> </div> </div> </div> </div> ) } export default App; |
CSS
body { background-color : yellow; } .markdown-editor, .rendered-output { height : 100% ; width : 100% ; padding : 10px ; } .markdown-textarea, .rendered-html-output { height : 60 vh; width : 100% ; overflow : auto ; } |
Step to Run Application: Run the application using the following command from the root directory of the project.
npm start
Output:
Contact Us