# Select

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

Lista de opções nativa (`<select>`) para escolher um valor, com sugestão inicial que não pode ser devolvida como resposta e estado de erro. No Chrome e no Edge a lista aberta ganha o estilo do sistema; nos outros navegadores, é a do sistema operacional.

- Função: Formulário e ação
- Também chamado de: lista suspensa, seletor, combo, select, dropdown de formulário
- Mora em: `app/components/atoms/Select.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/Select](https://phorte-design-system.vercel.app/styleguide/peca/Select)
- Ficha no Storybook: [components-base-select](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-select--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/Select/0](https://phorte-design-system.vercel.app/previa/Select/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 { Select } from '@/app/components/atoms/Select';

<Select>…</Select>
```

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/Select/0)
2. [Com valor](https://phorte-design-system.vercel.app/previa/Select/1)
3. [Desabilitado](https://phorte-design-system.vercel.app/previa/Select/2)
4. [Erro](https://phorte-design-system.vercel.app/previa/Select/3)

Para escolher um valor entre muitas opções conhecidas — estado, curso, modalidade —, dentro de um FormField.

### Quando não usar

Para poucas opções que valem ser vistas juntas, use o Radio. Para ações (editar, excluir), o Dropdown. Para filtrar uma lista na hora, o FilterGroup.

### Faça

- Use `placeholder` ("Selecione…"): vira uma opção desabilitada, que aparece enquanto nada foi escolhido.
- Use dentro de um FormField, que liga rótulo, dica e erro.
- Largura e margem pela `className` (vão para o invólucro, que posiciona a seta).

### Evite

- Trocar o `<select>` por uma lista feita à mão: o nativo traz teclado, leitor de tela e celular prontos.
- Pôr a largura no `<select>` por `classNameDoCampo`: o invólucro continua na linha toda e a seta fica fora do campo.
- Opção vazia escolhível como "nenhuma" — use o `placeholder`, que não volta como resposta.

### Nota de uso

A lista aberta é estilizada **só no Chrome e no Edge**, que suportam `appearance: base-select`. No Safari e no Firefox ela continua sendo a do sistema operacional — de propósito: estilo progressivo, sem trocar o `<select>` nativo por uma lista feita à mão. O foco é o do `Input`: borda de 2px em `--border-focus`, não mais vermelho. `placeholder` vira uma opção desabilitada, que não pode ser devolvida como resposta; `error` emite `aria-invalid`. Dê largura e margem pela `className`, que vai para o invólucro; para o `<select>` em si, `classNameDoCampo`.

### Anatomia

1. **Campo** — O `<select>`, com o mesmo contrato visual do Input (`campoVariants`) e espaço à direita para a seta.
2. **Seta** — Ícone `ChevronDown`, decorativo, sobre o campo.
3. **Lista** — As opções; a primeira, com `placeholder`, é desabilitada.

### Estados

| Estado | O que muda |
| --- | --- |
| Padrão | Borda `--border-interactive`; com `placeholder`, começa na sugestão. |
| Foco | Borda `--border-focus` de 2px, por CSS — não mais vermelha. |
| Aberto | No Chrome e no Edge, a lista estilizada (`appearance: base-select`) sob o campo. |
| Erro | `error` ou `aria-invalid`: borda vermelha e `aria-invalid` no campo. |
| Desabilitado | 50% de opacidade, cursor proibido e fora do Tab — medido. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Sem `value` nem `defaultValue`, com `placeholder` | Começa na sugestão, que não pode ser escolhida de volta. |
| Lista aberta e Tab | Fecha sem mudar o valor — medido. |

### Relacionados

- [Radio](https://phorte-design-system.vercel.app/styleguide/md/Radio.md) — Para poucas opções, todas à vista.
- [Dropdown](https://phorte-design-system.vercel.app/styleguide/md/Dropdown.md) — Para ações, não valores.
- [FormField](https://phorte-design-system.vercel.app/styleguide/md/FormField.md) — Rótulo, dica e erro ligados ao campo.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `error` | `boolean` | — | não | Pinta a borda de erro **e** emite `aria-invalid`, como no `Input`. |
| `placeholder` | `string` | — | não | Texto de sugestão ("Selecione…"). Vira a primeira opção, **desabilitada**: aparece enquanto nada foi escolhido e não pode ser devolvida como resposta. Sem `value` nem `defaultValue`, o campo começa nela. |
| `classNameDoCampo` | `string` | — | não | Classes do `<select>` em si. A `className` vai para a caixa externa. |

Aceita também: `React.SelectHTMLAttributes<HTMLSelectElement>`.

### Medidas

| Parte | Valor | Classe |
| --- | --- | --- |
| Altura com texto `text-sm` | 46px (medido) | `px-4 py-3` |
| Espaço da seta | 40px à direita | `pr-10` |

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--muted-foreground` | #595959 | `text-muted-foreground` |

## Acessibilidade

### Teclado

| Tecla | Faz |
| --- | --- |
| Tab | Leva o foco ao campo. Desabilitado é pulado. |
| Enter / Espaço / ↓ | Com a lista fechada, abre a lista na opção atual (ou na primeira escolhível) — medido no Chrome. |
| ↑ / ↓ / Home / End | Com a lista aberta, andam pelas opções **sem escolher**. |
| Enter / Espaço | Com a lista aberta, escolhem a opção em foco e fecham a lista. |
| Esc | Fecha a lista sem mudar o valor. |
| Letra | Com a lista fechada, escolhe direto a opção que começa com ela — medido: "e" escolhe EAD. |

### Leitor de tela

- É o `<select>` nativo: papel, valor e lista são anunciados pelo navegador e pelo leitor, sem ARIA de reforço.
- A tabela de teclado foi medida no Chrome, com a lista estilizada; no Safari e no Firefox vale o teclado da lista do sistema.

### O que sustenta o estado

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

## Status e recursos

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

- `bcf9541` 2026-09-28 — Merge pull request #13 from srbunnie/ds/roteiro-final
- Histórico completo no GitHub: https://github.com/srbunnie/Pos-Phorte-Design-System/commits/main/app/components/atoms/Select.tsx
