Home > OS >  transition effect is not working for mobile menu in react js with styled components
transition effect is not working for mobile menu in react js with styled components

Time:04-04

I am trying to build a mobile menu with the effect that it slides in from the right side when the button is clicked. The sliding is working fine but it opens abruptly and closes too as the transition is not having any effect on it. In the inspect element is shows that transition property is checked but it is still not having any effect. Below is my code

elements

function Header() {
  const [burgerStatus, setBurgerStatus] = useState(false);

  return (
    <Nav
      initial={{ y: "-100%" }}
      animate={{
        y: 0,
        transition: {
          duration: 0.5,
        },
      }}
    >
      <NavLink to="/">
        <Logo src="/images/logo_name_header.svg" />
      </NavLink>

      <HamburgerButton onClick={() => setBurgerStatus((curr) => !curr)}>
        {burgerStatus ? (
          <i ></i>
        ) : (
          <i ></i>
        )}
      </HamburgerButton>

      <NavMenu>
        <ul>
          <li>
            <NavLink activeclassname="acitve" to="/">
              <span>Home</span>
            </NavLink>
          </li>
          <li>
            <NavLink activeclassname="acitve" to="/service">
              <span>Services</span>
            </NavLink>
          </li>

          <li>
            <NavLink activeclassname="acitve" to="/about-us">
              <span>About Us</span>
            </NavLink>
          </li>
          <li>
            <NavLink activeclassname="acitve" to="/contact">
              <span>Contact Us</span>
            </NavLink>
          </li>

          <li>
            <NavLink activeclassname="acitve" to="/register">
              <div className="cta-register">Register</div>
            </NavLink>
          </li>

          <li>
            <NavLink activeclassname="acitve" to="/login">
              <span>Login</span>
            </NavLink>
          </li>
        </ul>
      </NavMenu>
      {burgerStatus && (
        <MobileMenu show={burgerStatus}>
          <NavLink activeclassname="acitve" to="/">
            <span>Home</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/service">
            <span>Services</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/about-us">
            <span>About Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/contact">
            <span>Contact Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/register">
            <span>Register</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/login">
            <span>Login</span>
          </NavLink>
        </MobileMenu>
      )}
    </Nav>
  );
}

export default Header;

styled components

const Nav = styled(motion.div)`
  user-select: none;
  position: sticky;
  top: 0;
  right: 0;
  left: 0;
  height: 4.375rem;
  background: #fff;
  display: flex;
  align-items: center;
  padding: 2rem 1rem;
  border-bottom: 1px solid #dadce0;

  z-index: 20;

  @media (max-width: 480px) {
    padding-inline: 0.5rem;
  }
`;


const MobileMenu = styled.nav`
  /* outline: 1px solid red; */
  font-size: 1rem;
  font-weight: 500;
  font-family: "Poppins", sans-serif;
  position: fixed;
  height: 100vh;
  inset: 0 0 0 40%;
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: min(30vh, 10rem) 2rem;
  gap: 3rem;
  background: hsl(0deg 0% 33% / 10%);
  backdrop-filter: blur(1.5rem);
  z-index: 16;
  transform: ${(props) => (props.show ? "translateX(0%)" : "translateX(100%)")};
  transition: transform 0.3s ease-out;
  a {
    text-decoration: none;
    span {
      letter-spacing: 0.06rem;
      position: relative;
      color: #000;
    }
  }
  .active {
    span {
      color: #1a73e8;
    }
  }

  @media (min-width: 700px) {
    display: none;
  }
`;


Please correct where I am writing wrong.

CodePudding user response:

burgerStatus check is causing that animation problem

{burgerStatus && (
        <MobileMenu show={burgerStatus}>
          <NavLink activeclassname="acitve" to="/">
            <span>Home</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/service">
            <span>Services</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/about-us">
            <span>About Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/contact">
            <span>Contact Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/register">
            <span>Register</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/login">
            <span>Login</span>
          </NavLink>
        </MobileMenu>
      )}

whenever burgerStatus changes to true/false, your entire component will be re-rendered for updating MobileMenu display immediately.

If you already handle showing/hiding on show={burgerStatus} properly with

transform: ${(props) => (props.show ? "translateX(0%)" : "translateX(100%)")};`

You don't need to have that burgerStatus for re-rendering MobileMenu

<MobileMenu show={burgerStatus}>
          <NavLink activeclassname="acitve" to="/">
            <span>Home</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/service">
            <span>Services</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/about-us">
            <span>About Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/contact">
            <span>Contact Us</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/register">
            <span>Register</span>
          </NavLink>

          <NavLink activeclassname="acitve" to="/login">
            <span>Login</span>
          </NavLink>
        </MobileMenu>
  • Related