Search code examples
javascriptcssreactjsreact-css-modules

Use Css modules add conditional transition styling to my side navigation


I would like to add some transition styling to my side navigation on my app. I am able to do this using normal classes however in this tutorial they use css modules and i am unsure how to do this using css modules.

I would like my nav to glide in and out, at the moment it jumps statically when the onClick function fires - toggleSideDrawer.

I have used this logic but I am not sure if it is doing anything:

className={props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer

Essentially i want that when the user clicks the toggle, the transform property switches from translateX(-100%) to translateX(0) but this is not happening.

Side nav code:

import React from "react";
import Logo from "../../Logo/Logo";
import NavigationItems from "../NavigationItems/NavigationItems";
import Backdrop from "../../UI/Backdrop/Backdrop";
import Aux from "../../../hoc/Aux";

import classes from "./SideDrawer.css";

const SideDrawer = props => {
  return (
    <Aux classname={classes.SideDrawer}>
      <Backdrop
        showBackdrop={props.showSideDrawer}
        clicked={props.toggleSideDrawer}
      />
      {props.showSideDrawer && (
        <div
          onClick={props.toggleSideDrawer}
          className={
            props.toggleSideDrawer ? classes.SideDrawerOpen : classes.SideDrawer
          }
        >
          <div className={classes.Logo}>
            <Logo />
          </div>

          <nav>
            <NavigationItems />
          </nav>
        </div>
      )}
    </Aux>
  );
};

export default SideDrawer;

Where the code is used in my Layout component:

import React, { useState } from "react";
import Aux from "../Aux";

import classes from "./Layout.css";
import Toolbar from "../../components/Navigation/Toolbar/Toolbar";
import SideDrawer from "../../components/Navigation/SideDrawer/SideDrawer";

const layout = props => {
  const [showSideDrawer, setShowSideDrawer] = useState(false);

  return (
    <Aux>
      <SideDrawer
        showSideDrawer={showSideDrawer}
        toggleSideDrawer={() => {
          setShowSideDrawer(!showSideDrawer);
        }}
      />
      <Toolbar
        onMenuClick={() => {
          setShowSideDrawer(!showSideDrawer);
        }}
      />
      <main className={classes.mainContent}> {props.children} </main>
    </Aux>
  );
};
export default layout;

CSS:

.SideDrawer {
  position: fixed;
  width: 280px;
  max-width: 70%;
  height: 100%;
  left: 0;
  top: 0;
  z-index: 200;
  background-color: white;
  padding: 32px 16px;
  box-sizing: border-box;
  transform: translateX(-100%);
}
@media (min-width: 500px) {
  .SideDrawer {
    display: none;
  }
}

.Logo {
  height: 11%;
  text-align: center;
}
.SideDrawerOpen {
  position: fixed;
  width: 280px;
  max-width: 70%;
  height: 100%;
  left: 0;
  top: 0;
  z-index: 200;
  padding: 32px 16px;
  box-sizing: border-box;
  background-color: red;
  transform: translateX(0);
  transition: transform 0.3s ease-out;
}


Solution

  • The thing is that you need the element will has the transition rule all the time.

    My suggestion is to set a static class which which will hold all the styles and addd another one only for overriding transform to make it move.

    Something like that (it uses scss but it's easy to do it with css)

    .SideDrawer {
      position: fixed;
      width: 280px;
      max-width: 70%;
      height: 100%;
      left: 0;
      top: 0;
      z-index: 200;
      background-color: white;
      padding: 32px 16px;
      box-sizing: border-box;
      transition: transform .3s ease;
      transform: translateX(-100%);
    
      &.show {
        transform: translateX(0);
      }
    }
    
    export const App = () => {
      const [showSideDrawer, setShowSideDrawer] = useState(false);
      const sidebarClasses = classname([
        styles.SideDrawer,
        {
          [styles.show]: showSideDrawer
        }
      ]);
      const ToggleSidebar = () => {
        return (
          <button onClick={() => setShowSideDrawer(!showSideDrawer)}>
            Toggle Sidebar
          </button>
        );
      };
    
      return (
        <Fragment>
          <h1>App</h1>
          <div className={sidebarClasses}>
            <div>Sidebar content</div>
            <ToggleSidebar />
          </div>
          <ToggleSidebar />
        </Fragment>
      );
    };
    

    https://codesandbox.io/s/xenodochial-framework-04sbe?file=/src/App.jsx