# Abas

> Componentes / Navegação e estrutura · Estado: **Em andamento** — Implementado e utilizável, mas ainda sem a validação completa de acessibilidade.

Abas 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`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/Abas](https://phorte-design-system.vercel.app/styleguide/peca/Abas)
- Ficha no Storybook: [components-complex-abas](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-complex-abas--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/Abas/0](https://phorte-design-system.vercel.app/previa/Abas/0)
- Todas as peças: [https://phorte-design-system.vercel.app/llms.txt](https://phorte-design-system.vercel.app/llms.txt)

## Como usar no código

```tsx
import { Abas } from '@/app/components/molecules/Abas';

<Abas abas={…} rotulo={…}>…</Abas>
```

O `…` marca as props obrigatórias — ver *Propriedades*.

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/Abas/0)
2. [Com aba desabilitada](https://phorte-design-system.vercel.app/previa/Abas/1)
3. [Com aba em breve](https://phorte-design-system.vercel.app/previa/Abas/2)
4. [Ativação manual](https://phorte-design-system.vercel.app/previa/Abas/3)

Para alternar entre partes de um mesmo assunto sem sair da página — "Sobre o curso", "Grade", "Corpo docente", "Investimento".

### 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.

### Faça

- Dê um `rotulo` ao 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.

### Anatomia

1. **Lista** — `role="tablist"` com o `rotulo`, linha `--border` embaixo; rola na horizontal no celular.
2. **Aba** — `role="tab"`, 44px de altura, negrito 16px; a aberta em `--primary` com a barra de 4px embaixo.
3. **Painel** — `role="tabpanel"` ligado à aba, na ordem de Tab.

### Estados

| 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

- [CourseTabs](https://phorte-design-system.vercel.app/styleguide/md/CourseTabs.md) — Botões de alternância da página de curso, sem o contrato de abas.
- [FilterGroup](https://phorte-design-system.vercel.app/styleguide/md/FilterGroup.md) — Para filtrar uma lista.
- [Accordion](https://phorte-design-system.vercel.app/styleguide/md/Accordion.md) — Conteúdo em sequência, recolhível.

## Especificação

### Propriedades

| 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

| Token | Valor | Usado como |
| --- | --- | --- |
| `--primary` | #D42B2B | `bg-primary`, `text-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` |

## Acessibilidade

### 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. |
| Home / End | Vai à primeira ou à última — conferido no teste da ficha. |
| Enter / Espaço | Na ativação manual, abre a aba em foco. |

### Leitor de tela

- O contrato inteiro de abas: `aria-selected`, `aria-controls` e o painel com `aria-labelledby` na 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

Usa os padrões: estatico. Falta ouvir com leitor de tela: estatico.

## Status e recursos

| Tipo | Recurso | Status |
| --- | --- | --- |
| Código | `app/components/molecules/Abas.tsx` | Disponível |
| Ficha | https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-complex-abas--docs | 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

- `0298af8` 2026-09-30 — E147: fechamento da Entrega 11 — REPORT.md, verificação cross-agent e o gate estático estrito
- Histórico completo no GitHub: https://github.com/srbunnie/Pos-Phorte-Design-System/commits/main/app/components/molecules/Abas.tsx
