All files / src/shared/Motion GiveMotionWrapper.tsx

94.44% Statements 17/18
76.19% Branches 16/21
83.33% Functions 5/6
94.11% Lines 16/17

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                                    194x                     13027x                   13027x 13027x 1860x 1487x 681x   1487x   373x       13027x 11412x     1615x                         194x               11412x   11412x                   11412x                
import { Box, Slide } from "@mui/material";
import React, { CSSProperties, memo, useEffect, useState } from "react";
import { animated, useInView, useSpring } from "react-spring";
 
type TGiveMotionWrapperProps = {
  children: React.ReactElement;
  type?: "fadeInUp" | "slide";
  delay?: number;
  duration?: number;
  direction?: "up" | "down" | "left" | "right";
  reset?: boolean;
  containerProps?: any;
  customStyle?: CSSProperties;
  inView?: boolean;
};
 
type TFadeInUp = Omit<TGiveMotionWrapperProps, "type">;
 
const GiveMotionWrapper = ({
  children,
  type = "fadeInUp",
  delay = 0,
  duration = 500,
  direction = "right",
  reset = false,
  containerProps,
  customStyle,
  inView = true,
}: TGiveMotionWrapperProps) => {
  const props = {
    children,
    delay,
    duration,
    reset,
    containerProps,
    customStyle,
  };
 
  //the logic is to manage the delay of the slide
  const [show, setShow] = useState(delay === 0 && inView);
  useEffect(() => {
    if (inView && delay > 0) {
      const timeoutId = setTimeout(() => {
        setShow(true);
      }, delay);
      return () => clearTimeout(timeoutId);
    } else {
      setShow(inView);
    }
  }, [inView, delay]);
 
  if (type === "fadeInUp") {
    return <FadeInUp {...props} />;
  }
 
  return (
    <Slide
      direction={direction}
      in={show}
      timeout={duration}
      mountOnEnter
      unmountOnExit
    >
      {children}
    </Slide>
  );
};
 
const FadeInUp = ({
  children,
  delay = 0,
  duration = 500,
  reset = false,
  containerProps,
  customStyle,
}: TFadeInUp) => {
  const [ref, inView] = useInView({ once: true });
 
  const styles = useSpring({
    opacity: inView ? 1 : 0,
    y: inView ? 0 : 50,
    from: { opacity: 0, y: 50 },
    config: { duration, easing: (t: any) => t * (2 - t) },
    delay: Math.min(delay, 1000),
    reset,
    ...customStyle,
  });
 
  return (
    <Box ref={ref} width="100%" {...containerProps}>
      <animated.div style={styles}>{children}</animated.div>
    </Box>
  );
};
 
export default memo(GiveMotionWrapper);