dressed_for_succes_store/components/TabSelector.tsx

102 lines
3.4 KiB
TypeScript

"use client"
import { useState, useRef, useEffect } from "react"
const tabs = ["Новинки", "Коллекции", "Популярное"]
interface TabSelectorProps {
onTabChange: (index: number) => void;
}
export default function TabSelector({ onTabChange }: TabSelectorProps) {
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null)
const [activeIndex, setActiveIndex] = useState(0)
const [hoverStyle, setHoverStyle] = useState({})
const [activeStyle, setActiveStyle] = useState({ left: "0px", width: "0px" })
const tabRefs = useRef<(HTMLDivElement | null)[]>([])
useEffect(() => {
if (hoveredIndex !== null) {
const hoveredElement = tabRefs.current[hoveredIndex]
if (hoveredElement) {
const { offsetLeft, offsetWidth } = hoveredElement
setHoverStyle({
left: `${offsetLeft}px`,
width: `${offsetWidth}px`,
})
}
}
}, [hoveredIndex])
useEffect(() => {
const activeElement = tabRefs.current[activeIndex]
if (activeElement) {
const { offsetLeft, offsetWidth } = activeElement
setActiveStyle({
left: `${offsetLeft}px`,
width: `${offsetWidth}px`,
})
}
// Вызываем функцию обратного вызова при изменении активного таба
onTabChange(activeIndex);
}, [activeIndex, onTabChange])
useEffect(() => {
requestAnimationFrame(() => {
const firstElement = tabRefs.current[0]
if (firstElement) {
const { offsetLeft, offsetWidth } = firstElement
setActiveStyle({
left: `${offsetLeft}px`,
width: `${offsetWidth}px`,
})
}
})
}, [])
return (
<div className="flex justify-center items-center w-full py-8 bg-white">
<div className="w-full max-w-[1200px] h-[60px] relative flex items-center justify-center">
<div className="p-0">
<div className="relative">
{/* Hover Highlight */}
<div
className="absolute h-[30px] transition-all duration-300 ease-out bg-[#0e0f1114] rounded-[6px] flex items-center"
style={{
...hoverStyle,
opacity: hoveredIndex !== null ? 1 : 0,
}}
/>
{/* Active Indicator */}
<div
className="absolute bottom-[-6px] h-[2px] bg-black transition-all duration-300 ease-out"
style={activeStyle}
/>
{/* Tabs */}
<div className="relative flex space-x-[24px] items-center">
{tabs.map((tab, index) => (
<div
key={index}
ref={(el) => (tabRefs.current[index] = el)}
className={`px-3 py-2 cursor-pointer transition-colors duration-300 h-[30px] ${
index === activeIndex ? "text-black font-medium" : "text-gray-500"
}`}
onMouseEnter={() => setHoveredIndex(index)}
onMouseLeave={() => setHoveredIndex(null)}
onClick={() => setActiveIndex(index)}
>
<div className="text-sm leading-5 whitespace-nowrap flex items-center justify-center h-full">
{tab}
</div>
</div>
))}
</div>
</div>
</div>
</div>
</div>
)
}