({
progress = 0,
animationComplexity = 'full',
layout = 'horizontal',
activeTab: controlledActiveTab,
onTabChange,
}: CompetitionTabsProps)
| 91 | } |
| 92 | |
| 93 | export function CompetitionTabs({ |
| 94 | progress = 0, |
| 95 | animationComplexity = 'full', |
| 96 | layout = 'horizontal', |
| 97 | activeTab: controlledActiveTab, |
| 98 | onTabChange, |
| 99 | }: CompetitionTabsProps) { |
| 100 | const [internalActiveTab, setInternalActiveTab] = |
| 101 | useState<CompetitorType>('cursor') |
| 102 | |
| 103 | const activeTab = |
| 104 | controlledActiveTab !== undefined ? controlledActiveTab : internalActiveTab |
| 105 | const isMobile = useIsMobile() |
| 106 | |
| 107 | const isVertical = layout === 'vertical' && !isMobile |
| 108 | |
| 109 | const handleTabClick = (tab: CompetitorType) => { |
| 110 | if (onTabChange) { |
| 111 | onTabChange(tab) |
| 112 | } else { |
| 113 | setInternalActiveTab(tab) |
| 114 | } |
| 115 | } |
| 116 | |
| 117 | useEffect(() => { |
| 118 | if (controlledActiveTab !== undefined) return |
| 119 | |
| 120 | const tabThreshold = 100 / competitors.length |
| 121 | const tabIndex = Math.min( |
| 122 | Math.floor(progress / tabThreshold), |
| 123 | competitors.length - 1, |
| 124 | ) |
| 125 | |
| 126 | if (progress > 0) { |
| 127 | setInternalActiveTab(competitors[tabIndex]) |
| 128 | } |
| 129 | }, [progress, controlledActiveTab]) |
| 130 | |
| 131 | return ( |
| 132 | <div |
| 133 | className={cn('h-full', isVertical ? 'flex flex-row' : 'flex flex-col')} |
| 134 | > |
| 135 | <div |
| 136 | className={cn( |
| 137 | isVertical |
| 138 | ? 'w-1/4 p-2 flex flex-col border-r border-zinc-800/50 bg-black/10' |
| 139 | : isMobile |
| 140 | ? 'p-1 grid grid-cols-4 gap-1 border-b border-zinc-800/50 bg-black/10' |
| 141 | : 'p-2 flex border-b border-zinc-800/50 bg-black/10', |
| 142 | 'min-h-[40px]', |
| 143 | )} |
| 144 | role="tablist" |
| 145 | aria-orientation={isVertical ? 'vertical' : 'horizontal'} |
| 146 | > |
| 147 | {competitors.map((competitor) => ( |
| 148 | <motion.button |
| 149 | key={competitor} |
| 150 | role="tab" |
nothing calls this directly
no test coverage detected