Container for react-modal content

97 views Asked by At

Our web app is 1280px wide and centered. I am working on adding a modal using the react-modal package. I would like a container above the ReactModal__Content ReactModal__Content--after-open container, but under the overlay container. Because I still want the overlay to take up the entire screen. But then I want the content to be in a 1280px wide container and pushed all the way to the right in that container. I tried the parentSelector property but that put everything including the overlay inside the container. So when I try and move the content container around it is still moving relative to the overlay container which is 100% of the screen. Is this possible with react-modal?

My modal styles look like this:

import { Styles } from 'react-modal';

export const ModalStyles: Styles = {
    content: {
        position: 'relative',
        width: '900px',
        margin: '50px auto',
        border: '1px solid #ccc',
        filter: 'blur(0)',
        opacity: 1,
        visibility: 'visible',
        boxShadow: '-2rem 2rem 2rem rgba(0, 0, 0, 0.5)',
        outline: 0,
        fontSize: '1.1em',
        fontWeight: 'bold',
        backgroundColor: '#FFFFFF',
        overflow: 'hidden'
    },
    overlay: {
        backgroundColor: 'rgba(255, 255, 255, 0.6)'
    }
};

This is how I am initiating the modal:

<Modal
            isOpen={openAddEditIngredientModal}
            style={ModalStyles}
            className={'quotes-modal'}
            closeTimeoutMS={1000}
            onAfterClose={() => cleanup()}
            parentSelector={() => document.querySelector('.modal-container')}
        >

Final html for modal container looks like this:

<div class="modal-container">
    <div class="ReactModalPortal">
        <div class="ReactModal__Overlay ReactModal__Overlay--after-open" style="position: fixed; inset: 0px; background-color: rgba(255, 255, 255, 0.6);">
            <div style="position: relative; width: 900px; margin: 50px auto; border: 1px solid rgb(204, 204, 204); filter: blur(0px); opacity: 1; visibility: visible; box-shadow: rgba(0, 0, 0, 0.5) -2rem 2rem 2rem; outline: 0px; font-size: 1.1em; font-weight: bold; background-color: rgb(255, 255, 255); overflow: hidden;" class="ReactModal__Content ReactModal__Content--after-open quotes-modal" tabindex="-1" role="dialog" aria-modal="true">
                <button class="sc-beyTiQ bIPUjR"></button>
                <h3 class="title">Add / Edit Ingredient</h3>
            </div>
        </div>
    </div>
</div>

And my CSS which does not affect the content container:

.modal-container {
    max-width: 1280px;
    padding: 0;
    margin: 0 auto;

    .quotes-modal {
        .title {
            background-color: #DDDDDD;
        }
    }
}
1

There are 1 answers

0
dmikester1 On

I figured out kind of a hack to get this to work the way I want it. I don't need the extra container between the overlay and the content. Instead, I calculated the coordinates I wanted to show the modal and the size(just the width actually) and made it absolutely positioned. I simply found the top and left coordinates of the container I wanted to put it on top of and also the width of that container.

So when I click the button to open the modal, this is my function:

const addIngredient = () => {
        setAddingIngredient(true);
        const ingredientsMain = document.querySelector('.ingredients-main');
        const ingRect = ingredientsMain.getBoundingClientRect();
        setModalData({
            x: ingRect.x + 5,
            y: ingRect.y + 5,
            width: ingRect.width - 10
        });
        setOpenAddEditIngredientModal(true);
    };

Then I am passing in that modalData to the modal. And I create my custom styles like this:

const customModalStyles = {
        content: {
            ...ModalStyles.content,
            position: 'absolute',
            left: modalData.x + 'px',
            top: modalData.y + 'px',
            bottom: '10px',
            width: modalData.width + 'px',
            margin: '0',
            boxShadow: '-1rem 1rem 1rem rgba(0, 0, 0, 0.5)'
        },
        overlay: { ...ModalStyles.overlay }
    };

There might be a better way to do this because it feels kind of hacky, hopefully not too fragile though. But this is all I could figure out for now.