Open In App

Designing a Markdown note taking application in ReactJS

Improve
Improve
Like Article
Like
Save
Share
Report

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:

Project Directory

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: 60vh;
    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:



Last Updated : 30 Nov, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads