"use client"; import { useEffect, useRef, useState } from "react"; export default function SeriesTabMenu({ tabs }) { const availableTabs = tabs.filter((tab) => tab.available); const [activeTab, setActiveTab] = useState(availableTabs[0]?.id); const refs = useRef({}); // Troca manual limpa o hash. Sem isso, depois de abrir o diagrama pelo link e // mudar de aba na mão, o hash continuaria em #connections e um novo clique no // link não dispararia hashchange e o botão pareceria quebrado. const trocarAba = (id) => { setActiveTab(id); if (window.location.hash) { history.replaceState(null, "", window.location.pathname + window.location.search); } }; // Abas endereçáveis por hash: #connections abre o diagrama de pinos direto. // É o que permite a seção de restrições apontar para cá. useEffect(() => { const abrirPeloHash = () => { const alvo = window.location.hash.replace("#", ""); if (alvo && availableTabs.some((t) => t.id === alvo)) { setActiveTab(alvo); // Nenhum elemento tem id="connections", então o navegador não rola // sozinho: levamos até as abas na mão. const semAnimacao = window.matchMedia("(prefers-reduced-motion: reduce)").matches; document.getElementById("diagrama-abas")?.scrollIntoView({ behavior: semAnimacao ? "auto" : "smooth", block: "start", }); } }; abrirPeloHash(); window.addEventListener("hashchange", abrirPeloHash); return () => window.removeEventListener("hashchange", abrirPeloHash); }, [availableTabs]); // Setas, Home e End movem o foco entre as abas, como no padrão WAI-ARIA. const aoTeclar = (evento, indice) => { const total = availableTabs.length; const destino = evento.key === "ArrowRight" ? (indice + 1) % total : evento.key === "ArrowLeft" ? (indice - 1 + total) % total : evento.key === "Home" ? 0 : evento.key === "End" ? total - 1 : null; if (destino === null) return; evento.preventDefault(); const id = availableTabs[destino].id; trocarAba(id); refs.current[id]?.focus(); }; if (availableTabs.length === 0) return null; const ativa = availableTabs.find((tab) => tab.id === activeTab) ?? availableTabs[0]; return (
{availableTabs.map((tab, indice) => ( ))}
{ativa.content}
); }