# ChatWindow

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

Janela de conversa de aula ao vivo: mensagens (que chegam sozinhas, simuladas, quando ao vivo), um botão para pausar essa chegada e o campo de envio. É um `role="log"` que anuncia só o que chega.

- Função: Conteúdo
- Também chamado de: chat, conversa, bate-papo, chat ao vivo
- Mora em: `app/components/organisms/ChatWindow.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/ChatWindow](https://phorte-design-system.vercel.app/styleguide/peca/ChatWindow)
- Ficha no Storybook: [components-complex-chatwindow](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-complex-chatwindow--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/ChatWindow/0](https://phorte-design-system.vercel.app/previa/ChatWindow/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 { ChatWindow } from '@/app/components/organisms/ChatWindow';

<ChatWindow isOpen={…} />
```

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

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/ChatWindow/0)
2. [Vazio](https://phorte-design-system.vercel.app/previa/ChatWindow/1)
3. [Ao Vivo](https://phorte-design-system.vercel.app/previa/ChatWindow/2)
4. [Fechado](https://phorte-design-system.vercel.app/previa/ChatWindow/3)

Ao lado de uma transmissão ao vivo, dentro de uma tela que traga o título e o botão de fechar.

### Quando não usar

Para um formulário de contato, use o ContactForm. Para uma mensagem do sistema, o Alert.

### Faça

- Traga o título e o fechar na tela que monta a janela: ela não tem cabeçalho próprio.
- Mantenha o botão de pausa: conteúdo que se atualiza sozinho precisa de como parar (WCAG 2.2.2).
- Use `isLive={false}` quando a transmissão acabou — o campo fica desabilitado e diz por quê.

### Evite

- Usar a simulação de mensagens em produção: os nomes e textos são sorteados no componente.
- Tirar o `role="log"`: sem ele, quem usa leitor de tela não sabe que alguém falou.

### Nota de uso

Tem controle de pausa para a simulação de mensagens ao vivo, dentro da própria região `role="log"` — sem ele, quem usa leitor de tela era interrompido a cada 8 segundos sem como parar. Se você for montar um chat, o botão de pausa não é enfeite: é o que a WCAG 2.2.2 exige de conteúdo que se atualiza sozinho.

### Anatomia

1. **Mensagens** — Região `role="log"` com rolagem própria, fundo `--muted`, e as mensagens numa lista (`ul`, E73).
2. **Pausa** — Só ao vivo: botão "Pausar as mensagens", no topo da região.
3. **Mensagem** — Nome e hora em cima; balão do sistema (vermelho claro), de outros (branco) ou seu (vermelho, à direita).
4. **Envio** — O Input do sistema, redondo, com rótulo escondido, e o Button "Enviar mensagem" no encaixe do fim (E73).

### Estados

| Estado | O que muda |
| --- | --- |
| Ao vivo | `isLive` (padrão): chega uma mensagem sorteada a cada 8 segundos e o botão de pausa aparece. |
| Pausado | Sem mensagens novas; o botão vira "Retomar as mensagens", com `aria-pressed="true"`. |
| Encerrado | `isLive={false}`: sem simulação, sem pausa, campo desabilitado ("Chat encerrado"). |
| Fechado | `isOpen={false}`: a janela sai esmaecendo. |
| Enviar indisponível | Com o campo vazio, o botão de enviar fica `aria-disabled` (continua focável, o clique não envia); encerrado, fica `disabled`. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Mensagem nova | Rola **o contêiner** até o fim (E73; o `scrollIntoView` de antes levava a página junto), suave, ou direto com movimento reduzido; o leitor anuncia só a nova (`aria-atomic="false"`). |
| Enter no campo com texto | Envia como "Você" e limpa o campo — medido; o foco fica no campo. |
| Enviar pelo botão | Envia, limpa o campo e devolve o foco a ele — medido no teste da ficha. |
| Movimento reduzido no sistema | A simulação já nasce parada (`usePausaDeMovimento`). |

### Relacionados

- [VideoPlayer](https://phorte-design-system.vercel.app/styleguide/md/VideoPlayer.md) — A transmissão ao lado do chat.
- [ContactForm](https://phorte-design-system.vercel.app/styleguide/md/ContactForm.md) — Para contato, não conversa.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `isOpen` | `boolean` | — | sim |  |
| `isLive` | `boolean` | `true` | não |  |
| `className` | `string` | — | não |  |
| `initialMessages` | `Message[]` | `[]` | não |  |

### Medidas

| Parte | Valor | Classe |
| --- | --- | --- |
| Enviar | 44 × 44px (medido) | `h-alvo-toque w-alvo-toque` |
| Campo | 48px de altura, borda de controle | `Input · classNameDoCampo="min-h-12 rounded-full"` |

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--primary` | #D42B2B | `bg-primary`, `text-primary` |
| `--border` | #E5E5E5 | `border-border` |
| `--border-interactive` | #8C8C8C | `border-border-interactive` |
| `--card` | #FFFFFF | `bg-card` |
| `--destructive` | #BA0517 | `border-destructive/25` |
| `--destructive-strong` | #BA0517 | `text-destructive-strong` |
| `--destructive-subtle` | #F9EBEC | `bg-destructive-subtle` |
| `--foreground` | #1A1A1A | `text-ink` |
| `--muted` | #F4F6F9 | `bg-muted` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |
| `--primary-foreground` | #FFFFFF | `text-primary-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 | Passa por "Pausar as mensagens" (ao vivo), pelo campo e por "Enviar mensagem" (indisponível com o campo vazio); encerrado, nada recebe foco. |
| Enter / Espaço | No botão de pausa, pausa ou retoma — medido. |
| Enter | No campo, envia a mensagem — medido. |

### Leitor de tela

- A região é `role="log"` com `aria-live="polite"`: mensagem de outra pessoa não corta o que está sendo lido.
- O botão de pausa fica dentro da região, no topo: quem chega ao log encontra como calá-lo antes da próxima mensagem.
- Cada mensagem é dita como frase — "Maria Silva, às 18:58: Boa noite a todos!" — por um texto `sr-only`; o desenho do nome, da hora e do balão é `aria-hidden` (E73, conferido no teste da ficha).

### O que sustenta o estado

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

## Status e recursos

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