NextUI modal with global state (open from anywhere)
Answered
American black bear posted this in #help-forum
American black bearOP
I am working on a solution which would make it possible to have (NextUI) Modal codes separated from components, and be able to open any modal from any component of the application. What I'm doing is I created a modal-store where I store the open close state of a modal and its 'type' and a ModalProvider where I just provide all the modals on root layout level. But currently nothing is happening when I open a modal. DO you have any tips? This is my code so far:
ModalProvider:
Modal Store:
NavigationBar:
SignInModal:
ModalProvider:
"use client";
import { useEffect, useState } from "react";
import SignInModal from "../(auth)/signin/sign-in-modal";
export const ModalProvider = () => {
const [isMounted, setIsMounted] = useState(false);
useEffect(() => {
setIsMounted(true);
}, []);
if (!isMounted) {
return null;
}
return (
<>
<SignInModal />
</>
);
};Modal Store:
import { create } from "zustand";
export type ModalType = "signIn"
interface ModalStore {
type: ModalType | null;
isOpen: boolean;
onModalOpen: (type: ModalType) => void;
onModalClose: () => void;
}
export const useModal = create<ModalStore>((set) => ({
type: null,
data: {},
isOpen: false,
onModalOpen: (type) => set({ isOpen: true, type }),
onModalClose: () => set({ type: null, isOpen: false }),
}));NavigationBar:
...
const { onModalOpen } = useModal();
...
<Button color="primary" onClick={() => onModalOpen('signIn')}>Sign in</Button>SignInModal:
const { isOpen, onModalClose, type } = useModal();
const isModalOpen = isOpen && type === "signIn";
return (
<>
<h1 className='text-red-500'>asdsadasdasdsadasdsadasdasdasd</h1>
<Modal
size={"md"}
isOpen={isModalOpen}
onClose={onModalClose}
>
...Answered by American black bear
<ModalContent> tag was missing from the Modal Body and without it nextui won't render the modal on the center of the screen10 Replies
ModalProvider is returning what you want to be rendered, but I don't see it being used anywhere
May be more reliable to properly use a context to manage the modal? I've had success with that method.
May be more reliable to properly use a context to manage the modal? I've had success with that method.
This way you just have a context that handles the state and a modal component which you render in the root layout
Then for example you can just import in any client component
import { openModal } from "@/context/modalContext"here's an example https://gist.github.com/Flohhhhh/975464ba69327273385f92b2d7b33eb7
Brown bear
Why need this code???
useEffect(() => {
setIsMounted(true);
}, []);
if (!isMounted) {
return null;
}I think You dont need this code and
ModalProviderYou can just import SignInModal into layout. then would be work
American black bearOP
Solved, thanks for help!
@American black bear Solved, thanks for help!
What is the solution?
@joulev What is the solution?
American black bearOP
<ModalContent> tag was missing from the Modal Body and without it nextui won't render the modal on the center of the screenAnswer