Neal Rogers
Neal Rogers

Reputation: 500

Trying to get Material ui dialog into contextualised modal

I have a modal component which I have put into context. If I return html , some divs etc, then no problem, but ideally I want to do this with the material-ui dialog.

But if I put in materail-ui dialog, as below, then nothing is displayed.

The component:

import React, { useCallback, useEffect, useState } from 'react'
import {Dialog, DialogActions, DialogContent, DialogContentText, DialogTitle} from "@material-ui/core";
import {useTranslation} from "react-i18next";
import {errorStyles} from "../errorStyle";

// Create a React context
const ModalContext = React.createContext(null);


//Declare the modal component
const Modal = ({ modal, unSetModal, errorClasses = errorStyles(),
             title, subtitle, children, }) => {
    useEffect(() => {
        const bind = e => {
            if (e.keyCode !== 27) {
                return
            }

        if (document.activeElement && ['INPUT', 'SELECT'].includes(document.activeElement.tagName)) {
            return
        }

        unSetModal()
    }

    document.addEventListener('keyup', bind)
    return () => document.removeEventListener('keyup', bind)
}, [modal, unSetModal])

const { t } = useTranslation()
return (
    <>
        <Dialog
            className={errorClasses.modal}
            fullWidth
            maxWidth='md'
            aria-labelledby='max-width-dialog-title'
        >
            <DialogTitle id='max-width-dialog-title'
                         className={errorClasses.header}>{title}</DialogTitle>
            <DialogContent>
                <DialogContentText>{subtitle}</DialogContentText>

            </DialogContent>
            <DialogActions>
                <button className={errorClasses.cancelButton}
                        onClick={unSetModal}>{t("Close")}</button>
            </DialogActions>
        </Dialog>
    </>
 )
}

const ModalProvider = props => {
    const [modal, setModal] = useState()
    const unSetModal = useCallback(() => {
        setModal('')
    }, [setModal])

    return (
        <ModalContext.Provider value={{ unSetModal, setModal }} {...props} >
            {props.children}
            {modal && <Modal modal={modal} unSetModal={unSetModal} />}
        </ModalContext.Provider>
    )
}

// useModal: shows and hides the Modal
const useModal = () => {
    const context = React.useContext(ModalContext)
    if (context === undefined) {
        throw new Error('useModal must be used within a UserProvider')
    }
    return context
}

export { ModalProvider, useModal }

And in another component (an edit form)

import { useModal, ModalProvider } from '../context/modal-context'
.....

export function DeviceModal (props) {
    const { setModal } = useModal()

    ...
    some other markup

    <div  style={{ position: 'sticky', bottom:'0', width:'100%', height:'40px',  paddingTop:'5px'}}>
        <Grid container direction="row-reverse" item xs={12} alignItems="right">
            <button className={classes.cancelButton}
                    onClick={() => { setModal(<></>)}} >
                    {'Cancel'}
            </button>
        </Grid>
    </div>

Hope someone can help Thanks

Upvotes: 1

Views: 1173

Answers (1)

Neal Rogers
Neal Rogers

Reputation: 500

Answer:

By adding the following to the dialogprops, it is resolved.

 open={true}
 backdropComponent={Backdrop}

and also, getting it to display values from the parent.

const ModalProvider = props => {
const [modal, setModal] = useState();
const [title, setTitle] = useState();
const [errMsg, setErrMsg] = useState();
const unSetModal = useCallback(() => {
    setModal('')
}, [setModal])


// Provide the Modals functions and state variables to the consuming parent component
return (
    <ModalContext.Provider value={{ unSetModal, setModal, setTitle, setErrMsg }} {...props} >
        {props.children}
        {modal && <Modal modal={modal} unSetModal={unSetModal} title={title} errMsg={errMsg} />}
    </ModalContext.Provider>
)}

In the parent use setTitle("yada yada") setErrMsg('more yerra yada");

Upvotes: 1

Related Questions