DEV Community

Elazizi Youssouf
Elazizi Youssouf

Posted on

Create React Modal with 22 lines of code

Nowadays, Modals are one of the most used components in React Application, having an easy way to create React Modals will help you sheep Modals related features fast in your upcoming React Applications.
In this tutorial, we will build A simple React Modal using only 22 lines of code.

The gif below will help you understand what we are trying to build

Let's started

Create React Project

First, create a simple react project using create-react-app cli

npx  Create-react-app  SimpleModal 
Enter fullscreen mode Exit fullscreen mode
import React from "react";
import ReactDOM from "react-dom";

import "./styles.css";

function App() {
  return (
    <div className="App">
      <h1>Create React Modal in X line of code </h1>
      <button>Click Me</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Enter fullscreen mode Exit fullscreen mode

In this tutorial, we will use the react-popup package which is a simple and Powerfull react component with a lot of benefits :

  • Modal, Tooltip, Menu: All in one πŸ‹οΈ
  • Full style customization πŸ‘Œ
  • Function as children pattern to take control over your popup anywhere in your code. πŸ’ͺ
  • IE Support. πŸš€
  • TypeScript Support πŸ‘Œ
  • All these clocks in at around 3 kB zipped. ⚑️

This package is available in npm repository as reactjs-popup. It will work correctly with all popular bundlers.

yarn add reactjs-popup
Enter fullscreen mode Exit fullscreen mode

Create React Modal

Import Popup Component from reactjs-popup and start using it like the following.
Add trigger property as a simple React Button element and set modal property to true.

import React from "react";
import ReactDOM from "react-dom";
import Popup from "reactjs-popup";

import "./styles.css";

function App() {
  return (
    <div className="App">
      <h1>Create React Modal with 22 line of code </h1>
      <Popup modal trigger={<button>Click Me</button>}>
        Modal Content
      </Popup>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Enter fullscreen mode Exit fullscreen mode

Customizing and Styling React Modal

we need to create a Content.js file for Modal Content component and add some style

//content.js
import React from "react";

export default ({ close }) => (
  <div className="modal">
    <a className="close" onClick={close}>
      &times;
    </a>
    <div className="header"> Modal Title </div>
    <div className="content">
      {" "}
      Lorem ipsum dolor sit amet consectetur adipisicing elit. Atque, a nostrum.
      Dolorem, repellat quidem ut, minima sint vel eveniet quibusdam voluptates
      delectus doloremque, explicabo tempore dicta adipisci fugit amet
      dignissimos?
      <br />
      Lorem ipsum dolor sit amet, consectetur adipisicing elit. Consequatur sit
      commodi beatae optio voluptatum sed eius cumque, delectus saepe
      repudiandae explicabo nemo nam libero ad, doloribus, voluptas rem alias.
      Vitae?
    </div>
  </div>
);


Enter fullscreen mode Exit fullscreen mode
/* index.css */ 
.modal {
  font-size: 12px;
}
.modal > .header {
  width: 100%;
  border-bottom: 1px solid gray;
  font-size: 18px;
  text-align: center;
  padding: 5px;
}
.modal > .content {
  width: 100%;
  padding: 10px 5px;
}
.modal > .actions {
  margin: auto;
}
.modal > .actions {
  width: 100%;
  padding: 10px 5px;
  text-align: center;
}
.modal > .close {
  cursor: pointer;
  position: absolute;
  display: block;
  padding: 2px 5px;
  line-height: 20px;
  right: -10px;
  top: -10px;
  font-size: 24px;
  background: #ffffff;
  border-radius: 18px;
  border: 1px solid #cfcece;
}

Enter fullscreen mode Exit fullscreen mode

Now it's time for some magic

Because reactjs-popup provides a child as function pattern, you have full control on Popup state

we will update our example to use a function as a child instead of a react element to implement close button.

//index.js
import React from "react";
import ReactDOM from "react-dom";
import Popup from "reactjs-popup";

import Content from "./Content.js";
import "./styles.css";

function App() {
  return (
    <div className="App">
      <h1>Create React Modal with 22 line of code </h1>
      <Popup modal trigger={<button>Click Me</button>}>
        {close => <Content close={close} />}
      </Popup>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Enter fullscreen mode Exit fullscreen mode

Final Result

reactjs-popup : https://react-popup.elazizi.com/
repo : https://github.com/yjose/create-react-modal-with-22-line-of-code
codesandbox :https://codesandbox.io/s/create-react-modal-with-22-lines-of-code-v2u7t

Make sure to visit react-popup home page

Thanks for reading! If you think other people should read this post and use this project, tweet, and share the post.

Remember to follow me, so you can get notified about my future posts.

Top comments (4)

Collapse
 
anpos231 profile image
anpos231 • Edited

Hmm, No focus management, no aria and the content outside the modal will be read by screen readers.

I prefer to have 2 nodes as a child of <body> tag.

  • #app - is the main container for your app, it will have aria-hidden="true" attribute set, if #modal contains any modals.
  • #modals - is a container for modals. The last node has the focus trap.

So how do you inject your components into #modals node?
You use react portals!

Collapse
 
elaziziyoussouf profile image
Elazizi Youssouf

yes @anpos231 , I am planning to implement this approach on the reactjs-popup next release

Collapse
 
anpos231 profile image
anpos231

Maybe don't use 'reactjs-popup'. It's not screen reader friendly and suffers from all the issues that I already mentioned above.

I'd suggest Reakit instead.
It supports full customisation and the entire framework is focused on accessibility.

Collapse
 
romanown profile image
roman

it's good when there is one simple app module. and if you need to call a dialog from a deep child element that is one of hundreds in the list?