fix: modal transition not working (#433)
This commit is contained in:
@@ -5,8 +5,10 @@ import {
|
|||||||
createContext,
|
createContext,
|
||||||
useCallback,
|
useCallback,
|
||||||
useContext,
|
useContext,
|
||||||
|
useEffect,
|
||||||
useReducer,
|
useReducer,
|
||||||
useRef,
|
useRef,
|
||||||
|
useState,
|
||||||
} from "react";
|
} from "react";
|
||||||
import { getDefaultZIndex, Modal } from "@mantine/core";
|
import { getDefaultZIndex, Modal } from "@mantine/core";
|
||||||
import { randomId } from "@mantine/hooks";
|
import { randomId } from "@mantine/hooks";
|
||||||
@@ -17,6 +19,7 @@ import { useI18n } from "@homarr/translation/client";
|
|||||||
|
|
||||||
import type { ConfirmModalProps } from "./confirm-modal";
|
import type { ConfirmModalProps } from "./confirm-modal";
|
||||||
import { ConfirmModal } from "./confirm-modal";
|
import { ConfirmModal } from "./confirm-modal";
|
||||||
|
import type { ModalsState, ModalStateWithReference } from "./reducer";
|
||||||
import { modalReducer } from "./reducer";
|
import { modalReducer } from "./reducer";
|
||||||
import type { inferInnerProps, ModalDefinition } from "./type";
|
import type { inferInnerProps, ModalDefinition } from "./type";
|
||||||
|
|
||||||
@@ -32,7 +35,6 @@ interface ModalContextProps {
|
|||||||
export const ModalContext = createContext<ModalContextProps | null>(null);
|
export const ModalContext = createContext<ModalContextProps | null>(null);
|
||||||
|
|
||||||
export const ModalProvider = ({ children }: PropsWithChildren) => {
|
export const ModalProvider = ({ children }: PropsWithChildren) => {
|
||||||
const t = useI18n();
|
|
||||||
const [state, dispatch] = useReducer(modalReducer, {
|
const [state, dispatch] = useReducer(modalReducer, {
|
||||||
modals: [],
|
modals: [],
|
||||||
current: null,
|
current: null,
|
||||||
@@ -80,9 +82,39 @@ export const ModalProvider = ({ children }: PropsWithChildren) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalContext.Provider value={{ openModalInner, closeModal }}>
|
<ModalContext.Provider value={{ openModalInner, closeModal }}>
|
||||||
{activeModals.map((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 } =
|
const { defaultTitle: _ignored, ...otherModalProps } =
|
||||||
modal.reference.modalProps;
|
modal.reference.modalProps;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
key={modal.id}
|
key={modal.id}
|
||||||
@@ -100,17 +132,12 @@ export const ModalProvider = ({ children }: PropsWithChildren) => {
|
|||||||
trapFocus={modal.id === state.current?.id}
|
trapFocus={modal.id === state.current?.id}
|
||||||
{...otherModalProps}
|
{...otherModalProps}
|
||||||
title={translateIfNecessary(t, modal.props.defaultTitle)}
|
title={translateIfNecessary(t, modal.props.defaultTitle)}
|
||||||
opened={state.modals.length > 0}
|
opened={opened}
|
||||||
onClose={handleCloseModal}
|
onClose={handleCloseModal}
|
||||||
>
|
>
|
||||||
{modal.reference.content}
|
{modal.reference.content}
|
||||||
</Modal>
|
</Modal>
|
||||||
);
|
);
|
||||||
})}
|
|
||||||
|
|
||||||
{children}
|
|
||||||
</ModalContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
interface OpenModalOptions {
|
interface OpenModalOptions {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useContext } from "react";
|
|||||||
import { ModalContext } from ".";
|
import { ModalContext } from ".";
|
||||||
import type { ModalDefinition, ModalState } from "./type";
|
import type { ModalDefinition, ModalState } from "./type";
|
||||||
|
|
||||||
type ModalStateWithReference = ModalState & {
|
export type ModalStateWithReference = ModalState & {
|
||||||
/**
|
/**
|
||||||
* Reference to modal component instance
|
* Reference to modal component instance
|
||||||
* Used so the modal can be persisted between navigating in newer modals
|
* Used so the modal can be persisted between navigating in newer modals
|
||||||
@@ -13,7 +13,7 @@ type ModalStateWithReference = ModalState & {
|
|||||||
reference: ReturnType<typeof getModal>;
|
reference: ReturnType<typeof getModal>;
|
||||||
};
|
};
|
||||||
|
|
||||||
interface ModalsState {
|
export interface ModalsState {
|
||||||
modals: ModalStateWithReference[];
|
modals: ModalStateWithReference[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user