import { cn } from '@/lib/utils' import { useDeepBrowsing } from '@/providers/DeepBrowsingProvider' import { ReactNode, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { ScrollArea, ScrollBar } from '../ui/scroll-area' type TabDefinition = { value: string label: string } export default function Tabs({ tabs, value, onTabChange, threshold = 800, options = null, active = false }: { tabs: TabDefinition[] value: string onTabChange?: (tab: string) => void threshold?: number options?: ReactNode active?: boolean }) { const { t } = useTranslation() const { deepBrowsing, lastScrollTop } = useDeepBrowsing() const tabRefs = useRef<(HTMLDivElement | null)[]>([]) const containerRef = useRef(null) const [indicatorStyle, setIndicatorStyle] = useState({ width: 0, left: 0 }) const updateIndicatorPosition = () => { const activeIndex = tabs.findIndex((tab) => tab.value === value) if (activeIndex >= 0 && tabRefs.current[activeIndex]) { const activeTab = tabRefs.current[activeIndex] const { offsetWidth, offsetLeft } = activeTab const padding = 24 // 12px padding on each side setIndicatorStyle({ width: offsetWidth - padding, left: offsetLeft + padding / 2 }) } } useEffect(() => { const animationId = requestAnimationFrame(() => { updateIndicatorPosition() }) return () => { cancelAnimationFrame(animationId) } }, [tabs, value]) useEffect(() => { if (!containerRef.current) return const resizeObserver = new ResizeObserver(() => { updateIndicatorPosition() }) const intersectionObserver = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { requestAnimationFrame(() => { updateIndicatorPosition() }) } }) }, { threshold: 0 } ) intersectionObserver.observe(containerRef.current) tabRefs.current.forEach((tab) => { if (tab) resizeObserver.observe(tab) }) return () => { resizeObserver.disconnect() intersectionObserver.disconnect() } }, [tabs, value]) return (
threshold && !active ? '-translate-y-[calc(100%+12rem)]' : '' )} >
{tabs.map((tab, index) => (
(tabRefs.current[index] = el)} className={cn( `w-fit text-center py-2 px-6 my-1 font-semibold whitespace-nowrap clickable cursor-pointer rounded-xl transition-all duration-200`, value === tab.value ? 'text-foreground' : 'text-muted-foreground hover:text-foreground' )} onClick={() => { onTabChange?.(tab.value) }} > {t(tab.label)}
))}
{options &&
{options}
}
) }