Animated tab navigation

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.

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>

)

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🔥🔥🔥

Leave a Reply

Your email address will not be published. Required fields are marked *