DEV Community

Vladislav Voloshanovskiy
Vladislav Voloshanovskiy

Posted on

Animated tab navigation

I had a task to make an animated page transition. we can find a similar animation behavior in telegram when we switch folders.
Image description
My site is written in react, not react native. we are making a mobile application that runs in the browser.
there is a component in which I have buttons to switch between tabs.

const [selectedTab, setSelectedTab] = useState("documents");
const [indicatorStyle, setIndicatorStyle] = useState({});
const buttonContainerRef = useRef<HTMLDivElement>(null);
const documentsButtonRef = useRef(null);

   const handleClick = (tabName: string) => {
     setSelectedTab(tabName);
     setTimeout(() => {
       const activeButton = document.querySelector(
         `.${styles.activeButton}`
       ) as HTMLButtonElement | null;
       if (activeButton) {
         updateIndicatorDirectly(activeButton);
       }
     }, 0);
   };

   const updateIndicatorDirectly = (button: HTMLButtonElement) => {
     if (buttonContainerRef.current) {
       const { left } = buttonContainerRef.current.getBoundingClientRect();
       const { width, height, top } = button.getBoundingClientRect();

       setIndicatorStyle({
         minWidth: `${width}px`,
         top: `${top + height - 25}%`, // Скорректируйте значение по необходимости
         left: `${button.offsetLeft - left}px`,
         opacity: 1,
       });
     }
   };

   const getButtonClass = (tabName: string): string => {
     return selectedTab === tabName ? styles.activeButton : styles.button;
   };

 return ( 

<button
  ref={documentsButtonRef}
  className={getButtonClass("documents")}
  onClick={() => {
    handleClick("documents");
  }}>
    {currentButtonLabels.documents}
</button>
 <button
    className={getButtonClass("images")}
    onClick={() => {
      handleClick("images");
    }}>
      {currentButtonLabels.images}
 </button>
 <button
   className={getButtonClass("video")}
   onClick={() => {
      handleClick("video");
   }}>
     {currentButtonLabels.video}
 </button>

)
Enter fullscreen mode Exit fullscreen mode

Initially, the documents button is assigned an active class and our indicator. by clicking, the indicator moves and the active class changes as well.
Here is the result that I got🔥🔥🔥

Image description

Top comments (0)