Abas
Em andamentoAbas no padrão da WAI-ARIA, inteiro: tablist com nome, uma parada de Tab (a aba aberta), setas para trocar, Home e End, e cada painel ligado à sua aba. Ativação automática ou manual.
- Função
- Navegação e estrutura
- Também chamado de
- abas, guias, tabs, separadores
- Mora em
- app/components/molecules/Abas.tsx
- Última mudança
- 2026-09-30
Prévia
A peça ao vivo, vinda da ficha, na largura escolhida. Em larguras fixas, ela roda num quadro do tamanho de uma tela de verdade.
Na largura da página: 0px
Variantes na ficha
Lidas da ficha no build, na ordem do palco. Cada uma abre sozinha, sem o styleguide em volta — é o endereço que o palco carrega.
Quando usar
Para alternar entre partes de um mesmo assunto sem sair da página — "Sobre o curso", "Grade", "Corpo docente", "Investimento".
Faça
- Dê um
rotuloao conjunto: "Informações do curso". - Use de duas a seis abas, com rótulos curtos.
- Use
ativacao="manual"quando o painel custar a carregar: a seta só move o foco, e o Enter abre.
Evite
- Esconder numa aba o que quase todos precisam ver.
- Escrever "(em breve)" no rótulo: use
emBreve, que põe a etiqueta e a diz a quem ouve (E122). - Aba desabilitada sem motivo à vista: se ela volta, é
emBreve; se não, tire a aba. - Abas dentro de abas.
Quando não usar. Para filtrar uma lista, use o FilterGroup. Para navegar entre páginas, links. Para conteúdo que a pessoa lê em sequência, o Accordion ou a própria página.
Anatomia
As partes, na ordem em que o olho — e o teclado — passam.
- Lista — `role="tablist"` com o `rotulo`, linha `--border` embaixo; rola na horizontal no celular.
- Aba — `role="tab"`, 44px de altura, negrito 16px; a aberta em `--primary` com a barra de 4px embaixo.
- Painel — `role="tabpanel"` ligado à aba, na ordem de Tab.
Estados
Os estados que a peça tem no código, e o que muda em cada um.
| Estado | O que muda |
|---|---|
| Aberta | aria-selected="true", vermelha, com a barra embaixo — estado por cor e forma. |
| Fechada | --muted-foreground; no hover, --ink. Fora do Tab (tabIndex={-1}). |
| Desabilitada | A 50%, cursor proibido, pulada pelas setas, aria-disabled; não abre, e o painel dela não existe na página — a informação não aparece (E122, testado na ficha). |
| Em breve | Como a desabilitada, mais a etiqueta "Em breve" ao lado do rótulo, dita a quem ouve ("Investimento, Em breve") — E122, testado na ficha. |
| Foco | Anel por dentro da aba (ring-inset), para a barra que rola não cortá-lo. |
Comportamento
| Situação | O que acontece |
|---|---|
| Clique numa aba | Abre o painel dela e chama onTrocar. |
| Seta com ativação automática | Move o foco e abre a aba — conferido no teste da ficha. |
| Seta com ativação manual | Só move o foco; Enter ou Espaço abrem — conferido no teste da ficha. |
| Modo controlado | Com aba, quem manda é o consumidor; onTrocar recebe o id. |
Relacionados
Como usar no código
A importação e o menor uso, lidos do arquivo. O … marca as props obrigatórias.
import { Abas } from '@/app/components/molecules/Abas';
<Abas abas={…} rotulo={…}>…</Abas>Propriedades
Lidas do código da peça no build — não escritas à mão.
| Prop | Tipo | Padrão | Obrigatória | Descrição |
|---|---|---|---|---|
abas | Aba[] | — | sim | — |
rotulo | string | — | sim | Nome do conjunto, para quem ouve: "Informações do curso". |
abaInicial | string | — | não | A aba aberta de início (modo não controlado). Padrão: a primeira habilitada. |
aba | string | — | não | Presente = modo controlado. |
onTrocar | (id: string) => void | — | não | — |
ativacao | 'automatica' | 'manual' | 'automatica' | não | automatica (padrão): a seta já abre a aba — bom quando o painel é leve. manual: a seta só move o foco, e Enter ou Espaço abrem — para painel que custa carregar. |
Aceita também: Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'>.
Medidas
| Parte | Valor | Classe |
|---|---|---|
| Altura da aba | 44px | min-h-alvo-toque |
| Barra da aberta | 4px | h-1 |
Tokens de cor
Os tokens semânticos que o código da peça usa, com o valor de hoje em app/globals.css.
| Token | Valor | Usado como |
|---|---|---|
--primary | #D42B2B | bg-primarytext-primary |
--border | #E5E5E5 | border-border |
--foreground | #1A1A1A | text-ink |
--muted | #F4F6F9 | bg-muted |
--muted-foreground | #595959 | text-muted-foreground |
--ring | var(--footer-red)), decisão da revisão 2. Se outra peça precisar
* dele como superfície, o nome vira de papel (ex.: --surface-brand-strong). */
--footer-red: #7D1B1B | ring-ring |
Teclado
| Tecla | Faz |
|---|---|
| Tab | Entra no conjunto pela aba aberta (uma parada só); o próximo Tab vai ao painel aberto — conferido no teste da ficha. |
| →← | Vai à próxima ou à anterior, dando a volta e pulando a desabilitada e a em breve — conferido no teste da ficha. |
| HomeEnd | Vai à primeira ou à última — conferido no teste da ficha. |
| EnterEspaço | Na ativação manual, abre a aba em foco. |
Leitor de tela
O que é anunciado, e por quê.
- O contrato inteiro de abas:
aria-selected,aria-controlse o painel comaria-labelledbyna aba — é o que o CourseTabs não promete, e diz no código. - O painel aberto recebe foco (
tabIndex={0}), para o texto dele entrar no caminho do Tab mesmo sem nada focável dentro.
O que sustenta o estado
Esta peça usa estatico. O estado dela é o de quem já foi ouvido com leitor de tela nesses padrões — e não uma passada sobre esta peça em específico.
Falta ouvir: estatico — ver docs/a11y-screen-reader-checklist.md.
Status e recursos
| Tipo | Recurso | Status |
|---|---|---|
| Código | app/components/molecules/Abas.tsx | Disponível |
| Ficha | Storybook (abre em outra aba) | Disponível |
| Teste de acessibilidade | axe em npm run test | No gate de todo commit |
| Leitor de tela | Passada da E33 | Falta ouvir |
| Design | Figma | Desativado até a Fase 2 |
Histórico
Os últimos commits que tocaram o arquivo, lidos do git no build.
0298af82026-09-30E147: fechamento da Entrega 11 — REPORT.md, verificação cross-agent e o gate estático estrito
O histórico completo está no GitHub (abre em outra aba).