All files / src/components/common/Modal/ModalFactory/atoms AnimatedDialog.tsx

88.88% Statements 16/18
90% Branches 9/10
85.71% Functions 6/7
100% Lines 16/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109                            37x   37x                       192x 192x   192x           192x 96x     192x 35x     192x 35x 35x   35x 34x       192x 314x                                                                                                          
import React, { useEffect } from "react";
import { Dialog, DialogProps, Stack, SxProps, Theme } from "@mui/material";
import { NavigationType, useNavigationType } from "react-router-dom";
import { animated, useTransition } from "react-spring";
import { palette } from "@palette";
 
export type BaseModalProps = DialogProps & {
  width?: string | number;
  scroll?: DialogProps["scroll"];
  slotProps?: any;
  paperStyle?: React.CSSProperties;
  contentContainerSx?: SxProps<Theme>;
};
 
const Wrapper = animated(Dialog);
 
const AnimatedDialog: React.FC<BaseModalProps> = ({
  sx,
  children,
  width = "640px",
  open,
  scroll = "paper",
  slotProps,
  paperStyle,
  PaperProps = {},
  contentContainerSx = {},
  ...rest
}) => {
  const [isOpen, setIsOpen] = React.useState<boolean>(false);
  const navType: NavigationType = useNavigationType();
 
  const transitions = useTransition(isOpen, {
    from: { transform: "translateY(25px)" },
    enter: { transform: "translateY(0px)" },
    leave: { transform: "translateY(50px)" },
  });
 
  useEffect(() => {
    setIsOpen(open);
  }, [open]);
 
  useEffect(() => {
    Iif (navType === "POP" && isOpen) setIsOpen(false);
  }, [navType]);
 
  useEffect(() => {
    const handlePopstate = () => setIsOpen(false);
    window.addEventListener("popstate", handlePopstate);
 
    return () => {
      window.removeEventListener("popstate", handlePopstate);
    };
  }, []);
 
  return transitions((style, itemVisible) => (
    <Wrapper
      open={!isOpen ? isOpen : itemVisible}
      style={style}
      scroll={scroll}
      PaperProps={{
        ...PaperProps,
        style: {
          borderRadius: "12px",
          width,
          maxWidth: width,
          background: palette.neutral.white,
          top: "50%",
          transform: "translate(0, -50%)",
          ...paperStyle,
          ...PaperProps?.style,
        },
      }}
      slotProps={{
        ...slotProps,
        backdrop: {
          ...slotProps?.backdrop,
          sx: {
            background: palette.backdrop.main,
            ...slotProps?.backdrop?.sx,
          },
        },
      }}
      sx={{
        overscrollBehavior: "contain",
        "&::-webkit-scrollbar": {
          display: "none",
        },
        "&::-webkit-scrollbar-track": {
          display: "none",
        },
        ...sx,
      }}
      {...rest}
    >
      <Stack
        display="column"
        alignItems="stretch"
        justifyContent="flex-start"
        overflow="hidden"
        sx={contentContainerSx}
      >
        {children}
      </Stack>
    </Wrapper>
  ));
};
 
export default AnimatedDialog;