# Slider

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

Controle deslizante para escolher um número numa faixa: trilha preenchida até o valor, pontos de parada quando há `step`, e rótulos nas pontas para escala qualitativa. Por baixo, um `<input type="range">` nativo.

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

<Slider />
```

## Uso

### Variantes na ficha

1. [Contínuo](https://phorte-design-system.vercel.app/previa/Slider/0)
2. [Com paradas](https://phorte-design-system.vercel.app/previa/Slider/1)
3. [Com rótulos nas pontas](https://phorte-design-system.vercel.app/previa/Slider/2)
4. [Desabilitado](https://phorte-design-system.vercel.app/previa/Slider/3)

Quando o valor exato importa menos que a posição na faixa — desconto, intensidade, "mais rápido ou mais completo".

### Quando não usar

Para um número exato (idade, CEP, quantidade precisa), use o Input. Para poucas opções nomeadas, o Radio ou o Select.

### Faça

- Dê um `label`: é o nome do controle, e o valor aparece ao lado dele.
- Use `formatarValor` para mostrar a unidade ("35%", "R$ 400"); o mesmo texto vai para o leitor, por `aria-valuetext`.
- Use `rotuloMin` e `rotuloMax` quando a escala for qualitativa.
- Use `step` para paradas: até 21, aparecem como pontos na trilha.

### Evite

- Faixa enorme com passo 1 e sem teclado em mente: de 0 a 1000, a seta anda de 1 em 1.
- Esconder o valor: sem ele, a pessoa ajusta às cegas.

### Anatomia

1. **Rótulo e valor** — O `label` à esquerda e o valor formatado à direita (o valor fica fora do nome acessível).
2. **Trilha** — 12px de altura, em `--border-interactive`, preenchida em `--primary` até o valor.
3. **Pontos de parada** — Com `step`, até 21 pontos discretos sobre a trilha.
4. **Polegar** — 28px, branco com borda de controle e duas setas dentro — desenhado sobre o polegar nativo, que fica invisível e recebe o ponteiro. O tamanho tem uma fonte só, `--slider-polegar` (E61): os dois polegares e a posição do preenchimento leem dela.
5. **Pontas** — `rotuloMin` e `rotuloMax` embaixo, ligados ao controle por `aria-describedby` — somados à descrição que vier de fora (E61).

### Estados

| Estado | O que muda |
| --- | --- |
| Padrão | Trilha preenchida até o valor; polegar sobre ele. |
| Foco | O anel de foco (`anel-de-foco`) no polegar desenhado, pelo `peer-focus-visible`, só no teclado. |
| Desabilitado | Trilha e polegar a 50%, cursor proibido. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Arrastar ou clicar na trilha | O valor muda e o preenchimento e o polegar acompanham — o polegar nativo, invisível, é que recebe o ponteiro. |
| Com `step` | O valor anda de parada em parada — medido: de 40 a 60 a 80 com passo 20. |

### Relacionados

- [Input](https://phorte-design-system.vercel.app/styleguide/md/Input.md) — Para um número exato.
- [Radio](https://phorte-design-system.vercel.app/styleguide/md/Radio.md) — Para poucas opções nomeadas.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |
| `label` | `string` | — | não |  |
| `min` | `number` | `0` | não |  |
| `max` | `number` | `100` | não |  |
| `step` | `number` | `1` | não |  |
| `value` | `number` | — | não |  |
| `defaultValue` | `number` | — | não |  |
| `rotuloMin` | `string` | — | não | Rótulo na ponta esquerda, como "Mais rápido". |
| `rotuloMax` | `string` | — | não | Rótulo na ponta direita, como "Mais inteligente". |
| `formatarValor` | `(valor: number) => string` | `String` | não | Como o valor aparece ao lado do rótulo. Padrão: o número. |

Aceita também: `Omit<React.InputHTMLAttributes<HTMLInputElement>, 'type' | 'value' | 'defaultValue'>`.

### Medidas

| Parte | Valor | Classe |
| --- | --- | --- |
| Área do controle | 44px de altura | `h-alvo-toque` |
| Trilha | 12px | `h-3` |
| Polegar | 28 × 28px | `size-(--slider-polegar)` |
| Pontos de parada | 6px | `size-1.5` |

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--border-interactive` | #8C8C8C | `bg-border-interactive`, `border-border-interactive` |
| `--card` | #FFFFFF | `bg-card`, `bg-card/60` |
| `--foreground` | #1A1A1A | `text-ink` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |
| `--primary` | #D42B2B | `bg-primary` |
| `--primary-foreground` | #FFFFFF | `bg-primary-foreground/50` |

## Acessibilidade

### Teclado

| Tecla | Faz |
| --- | --- |
| Tab | Leva o foco ao controle; o anel acende no polegar. |
| → / ↑ | Aumenta um passo — medido: 35% → 36% → 37%. |
| ← / ↓ | Diminui um passo. |
| Page Up / Page Down | Aumenta ou diminui um passo maior — medido no Chrome: 10% da faixa (35% → 45%), nunca menos que o `step`. |
| Home / End | Vai ao mínimo ou ao máximo — medido: 0% e 100%. |

### Leitor de tela

- O valor é lido por `aria-valuetext`, já formatado ("36%"). O número ao lado do rótulo é `aria-hidden` — sem isso, o nome do controle mudaria a cada passo.
- Trilha, preenchimento, pontos e polegar desenhado são `aria-hidden`: quem ouve recebe tudo do `<input>`.
- Dentro de um FormField, a dica e o erro chegam pelo `aria-describedby` e somam-se às pontas (E61) — antes as pontas apagavam a descrição de fora.

### 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/Slider.tsx` | Disponível |
| Ficha | https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-base-slider--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/atoms/Slider.tsx
