({ workspace, className }: VTabBarProps)
| 185 | } |
| 186 | |
| 187 | export function VTabBar({ workspace, className }: VTabBarProps) { |
| 188 | const env = useWaveEnv<VTabBarEnv>(); |
| 189 | const activeTabId = useAtomValue(env.atoms.staticTabId); |
| 190 | const reinitVersion = useAtomValue(env.atoms.reinitVersion); |
| 191 | const documentHasFocus = useAtomValue(env.atoms.documentHasFocus); |
| 192 | const tabIds = workspace?.tabids ?? []; |
| 193 | |
| 194 | const [orderedTabIds, setOrderedTabIds] = useState<string[]>(tabIds); |
| 195 | const [dragTabId, setDragTabId] = useState<string | null>(null); |
| 196 | const [dropIndex, setDropIndex] = useState<number | null>(null); |
| 197 | const [dropLineTop, setDropLineTop] = useState<number | null>(null); |
| 198 | const [hoverResetVersion, setHoverResetVersion] = useState(0); |
| 199 | const [hoveredTabId, setHoveredTabId] = useState<string | null>(null); |
| 200 | const [isNewTabHovered, setIsNewTabHovered] = useState(false); |
| 201 | const dragSourceRef = useRef<string | null>(null); |
| 202 | const didResetHoverForDragRef = useRef(false); |
| 203 | const scrollContainerRef = useRef<HTMLDivElement>(null); |
| 204 | const scrollAnimFrameRef = useRef<number | null>(null); |
| 205 | const scrollDirectionRef = useRef<number>(0); |
| 206 | const scrollSpeedRef = useRef<number>(0); |
| 207 | |
| 208 | useEffect(() => { |
| 209 | setOrderedTabIds(tabIds); |
| 210 | }, [workspace?.tabids]); |
| 211 | |
| 212 | useEffect(() => { |
| 213 | if (reinitVersion > 0) { |
| 214 | setOrderedTabIds(workspace?.tabids ?? []); |
| 215 | } |
| 216 | }, [reinitVersion]); |
| 217 | |
| 218 | useEffect(() => { |
| 219 | if (activeTabId == null || scrollContainerRef.current == null) { |
| 220 | return; |
| 221 | } |
| 222 | const el = scrollContainerRef.current.querySelector(`[data-tabid="${activeTabId}"]`); |
| 223 | el?.scrollIntoView({ block: "nearest" }); |
| 224 | }, [activeTabId]); |
| 225 | |
| 226 | useEffect(() => { |
| 227 | if (!documentHasFocus || activeTabId == null || scrollContainerRef.current == null) { |
| 228 | return; |
| 229 | } |
| 230 | const el = scrollContainerRef.current.querySelector(`[data-tabid="${activeTabId}"]`); |
| 231 | el?.scrollIntoView({ block: "nearest" }); |
| 232 | }, [documentHasFocus]); |
| 233 | |
| 234 | const stopScrollLoop = useCallback(() => { |
| 235 | if (scrollAnimFrameRef.current != null) { |
| 236 | cancelAnimationFrame(scrollAnimFrameRef.current); |
| 237 | scrollAnimFrameRef.current = null; |
| 238 | } |
| 239 | scrollDirectionRef.current = 0; |
| 240 | }, []); |
| 241 | |
| 242 | const startScrollLoop = useCallback(() => { |
| 243 | if (scrollAnimFrameRef.current != null) { |
| 244 | return; |
nothing calls this directly
no test coverage detected