# EstadoVazio

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

O lugar do conteúdo que não há: a busca sem resultado, a lista de inscritos ainda vazia, o dia sem programação. Diz o que falta, em positivo, e o próximo passo, com uma ação só.

- Função: Estado e aviso
- Também chamado de: empty state, estado vazio, sem resultados, nenhum resultado, lista vazia
- Mora em: `app/components/molecules/EstadoVazio.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/EstadoVazio](https://phorte-design-system.vercel.app/styleguide/peca/EstadoVazio)
- Ficha no Storybook: [components-complex-estadovazio](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-complex-estadovazio--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/EstadoVazio/0](https://phorte-design-system.vercel.app/previa/EstadoVazio/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 { EstadoVazio } from '@/app/components/molecules/EstadoVazio';

<EstadoVazio titulo={…}>…</EstadoVazio>
```

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

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/EstadoVazio/0)
2. [Com link](https://phorte-design-system.vercel.app/previa/EstadoVazio/1)
3. [Sem ação](https://phorte-design-system.vercel.app/previa/EstadoVazio/2)
4. [Contorno](https://phorte-design-system.vercel.app/previa/EstadoVazio/3)
5. [No filtro](https://phorte-design-system.vercel.app/previa/EstadoVazio/4)

Quando uma lista, uma busca ou um painel não tem nada para mostrar — e a pessoa precisa saber que não é erro nem carregamento.

### Quando não usar

Quando algo falhou (a busca não respondeu, o envio deu erro): o Alert. Enquanto carrega: o Esqueleto. Para a página inteira que não existe: a página de erro.

### Faça

- Escreva o `titulo` em positivo, dizendo o que falta: "Nenhum curso encontrado", e não "Sua busca falhou".
- Dê o próximo passo na `descricao` e, se houver, uma `acao` que o faça ("Limpar filtros", "Ver todos os cursos").
- Ligue `anunciar` quando o vazio é resposta a um filtro ou busca na mesma tela.
- Acerte o `nivelDoTitulo` conforme a página (padrão `h3`).

### Evite

- Culpar quem usa ou usar tom de erro: vazio não é falha.
- Duas ações: a segunda disputa com a primeira; o resto vai no texto.
- Ícone que carrega o sentido sozinho: ele é decorativo, e o título diz tudo.

### Anatomia

1. **Ícone** — Da Lucide, 24px, num círculo de 56px com fundo `--card` e borda; decorativo.
2. **Título** — 18px, negrito, `--ink`; nível por prop.
3. **Descrição** — 14px, `--muted-foreground`, até 320px de largura.
4. **Ação** — O Button `outline` pequeno (44px de alvo); link com `href`, botão sem ele.

### Estados

| Estado | O que muda |
| --- | --- |
| Padrão | Fundo `--muted`, para marcar o lugar do conteúdo numa página clara. |
| Contorno | Borda tracejada e fundo `--card`, dentro de cartão ou painel. |
| Anunciado | Com `anunciar`, é `role="status"`: o leitor lê quando aparece. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| O filtro esvazia a lista | Com `anunciar`, o leitor ouve o título e a descrição, sem sair do filtro — testado na ficha. |
| A ação é acionada | Faz o `onClick` ou navega pelo `href`; quem chama decide o que volta (a lista, outra página) — testado na ficha. |

### Relacionados

- [Alert](https://phorte-design-system.vercel.app/styleguide/md/Alert.md) — Quando algo falhou, e não só faltou.
- [Esqueleto](https://phorte-design-system.vercel.app/styleguide/md/Esqueleto.md) — Enquanto o conteúdo carrega.
- [FilterGroup](https://phorte-design-system.vercel.app/styleguide/md/FilterGroup.md) — O filtro que costuma esvaziar a lista.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `superficie` | `'padrao' \| 'contorno'` | `'padrao'` | não | Variante do `cva`. |
| `titulo` | `string` | — | sim | O que falta, em positivo: "Nenhum curso encontrado", e não "Você errou a busca". |
| `descricao` | `React.ReactNode` | — | não | O que fazer a seguir, numa frase. |
| `icone` | `LucideIcon` | `Inbox` | não | Ícone da Lucide (padrão: a caixa vazia). Decorativo: o título diz o mesmo. |
| `acao` | `AcaoDoEstadoVazio` | — | não | Uma ação só, que leva ao próximo passo ("Limpar filtros", "Ver todos os cursos"). |
| `nivelDoTitulo` | `'h2' \| 'h3' \| 'h4'` | `'h3'` | não | Nível do título (padrão `h3`). Acerte conforme a página. |
| `anunciar` | `boolean` | `false` | não | Anuncia o estado quando ele aparece. Ligue quando o vazio é resposta a uma ação na mesma tela — um filtro, uma busca —, para quem usa leitor de tela saber que a lista esvaziou sem ir procurar. **Como (E144).** Era o bloco inteiro com `role="status"` — e ele nasce junto com a mensagem, quando a lista esvazia: região viva criada já com o texto não é anunciada com segurança (guia de toasts do A11Y.md). Agora o bloco visível fica sem papel, legível desde o servidor, e uma região `sr-only` nasce vazia e recebe o título (e a descrição) um instante depois. |

Aceita também: `Omit<React.HTMLAttributes<HTMLDivElement>, 'title'>`.

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--border` | #E5E5E5 | `border-border` |
| `--border-interactive` | #8C8C8C | `border-border-interactive` |
| `--card` | #FFFFFF | `bg-card` |
| `--foreground` | #1A1A1A | `text-ink` |
| `--muted` | #F4F6F9 | `bg-muted` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |

## Acessibilidade

### Teclado

| Tecla | Faz |
| --- | --- |
| Tab | Chega à ação, se houver; o resto não recebe foco. |
| Enter | Aciona a ação (o botão também responde ao Espaço). |

### Leitor de tela

- Com `anunciar`, uma região `sr-only` nasce vazia e recebe o título (e a descrição) um instante depois (E144): criada já com a mensagem, como era, ela não é anunciada com segurança. O bloco visível não tem papel, e sai legível do servidor — testado na ficha.
- O ícone é decorativo (`aria-hidden`): o título diz o que falta.
- Com `anunciar`, a região `status` é lida quando aparece, com o título e a descrição.

### O que sustenta o estado

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

## Status e recursos

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