diff --git a/packages/modals/src/index.tsx b/packages/modals/src/index.tsx index 461dec4ee..16e99c4b6 100644 --- a/packages/modals/src/index.tsx +++ b/packages/modals/src/index.tsx @@ -5,8 +5,10 @@ import { createContext, useCallback, useContext, + useEffect, useReducer, useRef, + useState, } from "react"; import { getDefaultZIndex, Modal } from "@mantine/core"; import { randomId } from "@mantine/hooks"; @@ -17,6 +19,7 @@ import { useI18n } from "@homarr/translation/client"; import type { ConfirmModalProps } from "./confirm-modal"; import { ConfirmModal } from "./confirm-modal"; +import type { ModalsState, ModalStateWithReference } from "./reducer"; import { modalReducer } from "./reducer"; import type { inferInnerProps, ModalDefinition } from "./type"; @@ -32,7 +35,6 @@ interface ModalContextProps { export const ModalContext = createContext(null); export const ModalProvider = ({ children }: PropsWithChildren) => { - const t = useI18n(); const [state, dispatch] = useReducer(modalReducer, { modals: [], current: null, @@ -80,39 +82,64 @@ export const ModalProvider = ({ children }: PropsWithChildren) => { return ( - {activeModals.map((modal) => { - const { defaultTitle: _ignored, ...otherModalProps } = - modal.reference.modalProps; - return ( - 0} - onClose={handleCloseModal} - > - {modal.reference.content} - - ); - })} + {activeModals.map((modal) => ( + + ))} {children} ); }; +interface ActiveModalProps { + modal: ModalStateWithReference; + state: ModalsState; + handleCloseModal: () => void; +} + +const ActiveModal = ({ modal, state, handleCloseModal }: ActiveModalProps) => { + const t = useI18n(); + + // The below code is used to animate the modal when it opens (using the transition) + // It is necessary as transition is not working when the modal is directly mounted and run + const [opened, setOpened] = useState(false); + useEffect(() => { + setTimeout(() => setOpened(true), 0); + }, []); + + const { defaultTitle: _ignored, ...otherModalProps } = + modal.reference.modalProps; + + return ( + + {modal.reference.content} + + ); +}; + interface OpenModalOptions { keepMounted?: boolean; title?: stringOrTranslation; diff --git a/packages/modals/src/reducer.tsx b/packages/modals/src/reducer.tsx index 52a6cfcd3..10bbd93ce 100644 --- a/packages/modals/src/reducer.tsx +++ b/packages/modals/src/reducer.tsx @@ -5,7 +5,7 @@ import { useContext } from "react"; import { ModalContext } from "."; import type { ModalDefinition, ModalState } from "./type"; -type ModalStateWithReference = ModalState & { +export type ModalStateWithReference = ModalState & { /** * Reference to modal component instance * Used so the modal can be persisted between navigating in newer modals @@ -13,7 +13,7 @@ type ModalStateWithReference = ModalState & { reference: ReturnType; }; -interface ModalsState { +export interface ModalsState { modals: ModalStateWithReference[]; /**