Darkbound
Darkbound

Reputation: 3434

React CSS Translate Transition not working

I am trying to animate a side menu, but for some reason it just wont work!

I read on a few answers that using a map to map the <li> items could be the issue (and I have tried with just a few items with static text), but that doesnt seem to be the problem.

Additionally, I have also put the generated items into a state, and wrapped the set with an useEffect to prevent retriggering of the map, still doesn't work. Only the transition is not working, the menu is appearing where it must appear, closes itself when I click the menu button, etc.

EDIT: I think it is worth mentioning that while working on it on my development server, when I am updating my css file (its not refreshing the page), when I change some of the styles that make the sidebar move, it moves with animation, so the animation is there, it is just not working when I am clicking the open/close button but it just appears instantly.

P.S. uuid() generates unique key for each element, so that is not an issue either.

export default function SideBar({ names, closeSidebarOnClick, show }) {
  const [robots, setRobots] = useState();

  useEffect(() => {
    setRobots(GenerateNavItems());
  }, names);

  function GenerateNavItems() {
    return names.map((robotName) => {
      return (
        <li key={uuid()} className={`nav-item`} onClick={() => {closeSidebarOnClick();}}>
          {robotName}
        </li>
      );
    });
  }
      
  return (
    <nav className={`sidebar ${show ? "show-sidebar" : ""}`}>
      <ul>{robots}</ul>
    </nav>
  );
}

.nav-item {
  padding-left: 15px;
  text-decoration: none;
  font-weight: bold;
}

.nav-item:hover {
  color: red;
  cursor: pointer;
}

.toggle-sidebar-button {
  user-select: none;
  cursor: pointer;
  padding-left: 1.5rem;
  padding-top: 0.5rem;
  border: none;
  background: transparent;
  z-index: 300;
  /* z-index: 50; */
}

.toggle-sidebar-button:active {
  border: none;
}

.toggle-sidebar-button-line {
  width: 35px;
  height: 5px;
  background-color: black;
  margin: 6px 0;
}

.sidebar {
  height: 100%;
  position: fixed;
  top: 0;
  left: 0;
  width: 200px;
  z-index: 200;
  background-color: white;
  transform: translateX(-100%);
  transition: transform 1s ease;
}

.sidebar.show-sidebar {
  transform: translateX(0);
}

.sidebar ul {
  height: 100%;
  list-style: none;
  padding-left: 3rem;
  padding-top: 3rem;
  display: flex;
  flex-direction: column;
}
<div id="root">
  <div class="content row">
    <div class="toggle-sidebar-button">
      <div class="toggle-sidebar-button-line"></div>
      <div class="toggle-sidebar-button-line"></div>
      <div class="toggle-sidebar-button-line"></div>
    </div>
    <nav class="sidebar ">
      <ul>
        <li class="nav-item">ROBOT 1</li>
        <li class="nav-item">ROBOT 2</li>
      </ul>
    </nav>
    <div class="rendered-robot col">
      <div>CHOOSE ROBOT</div>
    </div>
  </div>
</div>

Upvotes: 2

Views: 3457

Answers (2)

Brandi
Brandi

Reputation: 1

I was having this same issue, and uuid() WAS the problem. Simply using a different type of key solved the transition issue.

Upvotes: 0

Ishank
Ishank

Reputation: 2926

It's possible that as you are re-rendering the nav component so the transition is not been visible. I suggest you to try this experiment - In closeSidebarOnClickdont don't let this do a re-render and just use the - document.getElementsByTagName('nav')[0].classList.add('show-sidebar');

There is a way to create a React.createRef() or useRef as mentioned here but this again is not to be used frequently.

Well, it may be a bad practice but when it comes to css animations what is the alternative we have? I use these animations via redux all the time :) I think the dom must not be manipulated directly frequently but since this is a nav bar and likely there is only one nav in the entire app, this much shall be ok. Let me know in case you find a typical react way of getting css animations work.

Upvotes: 3

Related Questions