DEV Community

Vic-Orlands
Vic-Orlands

Posted on

Building a simple React Modal

I have always used the react-modal package whenever I wanted to use a modal in a project but along the way, I wanted to build mine from scratch and it was so easy that I wondered why I resorted to the npm package. This will be a short article and very apt so come along.

First, Lets create two components; A home and a modal component for better comprehension. In the home component, lets have a simple h1 tag with a button and a function

import React, { Component } from 'react';
import './Home.css';
import Modal from './Modal';

class Home extends Component {
    state = {
        open: true
    };

    openModal = (e) => {
        e.preventDefault();
        this.setState({
            open: !this.state.open
        });
    };

    render() {
        return (
            <main>
                <section>
                    <h1>React-Modal</h1>
                    <button
                        onClick={(e) => {
                            this.openModal(e);
                        }}>
                        Open Modal
                    </button>
                </section>

                <Modal open={this.state.open} onClose={this.openModal} />
            </main>
        );
    }
}

export default Home;
Enter fullscreen mode Exit fullscreen mode

and in the modal component, lets add same tags and a function too.

import React, { Component } from 'react';
import './Modal.css';

class Modal extends Component {
    onClose = (e) => {
        this.props.onClose && this.props.onClose(e);
    };

    render() {
        if (this.props.open) {
            return null;
        }

        return (
            <section className="modal-container" id="modal">
                <div className="modal-content">
                    <h1>Notify Me</h1>
                    <button onClick={this.onClose}>Close Modal</button>
                </div>
            </section>
        );
    }
}

export default Modal;
Enter fullscreen mode Exit fullscreen mode

Let me explain a bit...We are setting our initial state to true and on click of the button, our state will be updated to false. Then we import the modal component which we created and pass a prop of open and onClose to it.

On the modal component, we got the passed prop and returns null if our state is true and the onClose function changes the state from true to false when close-modal button is clicked.

Now, if we run this code, we will see the raw structure but the modal isnt working yet so let's head over to CSS and design the magic.

/* -------------Home.css--------------------- */

*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

main {
    text-align: center;
    padding-top: 20px;
}
Enter fullscreen mode Exit fullscreen mode
/* -------------Modal.css--------------------- */
*,
*::before,
*::after {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

.modal-container {
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    height: 100%;
    width: 100%;
    overflow: hidden;
    z-index: 99;
    background-color: rgba(0, 0, 0, 0.5);
}

.modal-content {
    background-color: #f4f4f4;
    margin: 50px auto;
    width: 467px;
    height: 400px;
    max-width: 100%;
    max-height: 100%;
    border: 1px solid #ccc;
    padding: 40px 60px;
    box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17);
}
Enter fullscreen mode Exit fullscreen mode

and that is all...the modal-container is used as the background overlay to dim the home page while the modal-content is displayed on it. You can style your modal and even animate it to appear from top, left, bottom, fade in as you wish...lets do a little slide-down animation and call it a wrap

/* -------------Modal.css--------------------- */
.modal-content {
    background-color: #f4f4f4;
    margin: 50px auto;
    width: 467px;
    height: 400px;
    max-width: 100%;
    max-height: 100%;
    border: 1px solid #ccc;
    padding: 40px 60px;
    box-shadow: 0 5px 8px 0 rgba(0, 0, 0, 0.2), 0 7px 20px 0 rgba(0, 0, 0, 0.17);
        animation: dropdwn ease-in-out 700ms;
}

@keyframes dropdwn {
    0% {
        opacity: 0;
        margin-top: -250px;
    }
    25% {
        opacity: 0.25;
        margin-top: -200px;
    }
    50% {
        opacity: 0.5;
        margin-top: -100px;
    }
    75% {
        opacity: 0.75;
        margin-top: -50px;
    }
    100% {
        opacity: 1;
        margin-top: 0px;
    }
}
Enter fullscreen mode Exit fullscreen mode

and that is all...Ciao

Discussion (0)