fix: modal transition not working (#433)
This commit is contained in:
@@ -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<ModalContextProps | null>(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 (
|
||||
<ModalContext.Provider value={{ openModalInner, closeModal }}>
|
||||
{activeModals.map((modal) => {
|
||||
const { defaultTitle: _ignored, ...otherModalProps } =
|
||||
modal.reference.modalProps;
|
||||
return (
|
||||
<Modal
|
||||
key={modal.id}
|
||||
zIndex={getDefaultZIndex("modal") + 1}
|
||||
display={modal.id === state.current?.id ? undefined : "none"}
|
||||
style={{
|
||||
userSelect: modal.id === state.current?.id ? undefined : "none",
|
||||
}}
|
||||
styles={{
|
||||
title: {
|
||||
fontSize: "1.25rem",
|
||||
fontWeight: 500,
|
||||
},
|
||||
}}
|
||||
trapFocus={modal.id === state.current?.id}
|
||||
{...otherModalProps}
|
||||
title={translateIfNecessary(t, modal.props.defaultTitle)}
|
||||
opened={state.modals.length > 0}
|
||||
onClose={handleCloseModal}
|
||||
>
|
||||
{modal.reference.content}
|
||||
</Modal>
|
||||
);
|
||||
})}
|
||||
{activeModals.map((modal) => (
|
||||
<ActiveModal
|
||||
key={modal.id}
|
||||
modal={modal}
|
||||
state={state}
|
||||
handleCloseModal={handleCloseModal}
|
||||
/>
|
||||
))}
|
||||
|
||||
{children}
|
||||
</ModalContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
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
|
||||
key={modal.id}
|
||||
zIndex={getDefaultZIndex("modal") + 1}
|
||||
display={modal.id === state.current?.id ? undefined : "none"}
|
||||
style={{
|
||||
userSelect: modal.id === state.current?.id ? undefined : "none",
|
||||
}}
|
||||
styles={{
|
||||
title: {
|
||||
fontSize: "1.25rem",
|
||||
fontWeight: 500,
|
||||
},
|
||||
}}
|
||||
trapFocus={modal.id === state.current?.id}
|
||||
{...otherModalProps}
|
||||
title={translateIfNecessary(t, modal.props.defaultTitle)}
|
||||
opened={opened}
|
||||
onClose={handleCloseModal}
|
||||
>
|
||||
{modal.reference.content}
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
interface OpenModalOptions {
|
||||
keepMounted?: boolean;
|
||||
title?: stringOrTranslation;
|
||||
|
||||
@@ -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<typeof getModal>;
|
||||
};
|
||||
|
||||
interface ModalsState {
|
||||
export interface ModalsState {
|
||||
modals: ModalStateWithReference[];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user