# FilterGroup

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

Fileira de pílulas que filtram uma lista na hora. No modo único (padrão) é um grupo de rádio — uma marcada por vez, com as setas; no modo múltiplo, cada pílula alterna. A marcada fica em vermelho **e** com o visto. Rola na horizontal quando não cabe.

- Função: Formulário e ação
- Também chamado de: filtros, pílulas, chips, categorias, filtro rápido
- Mora em: `app/components/molecules/FilterGroup.tsx`
- Página: [https://phorte-design-system.vercel.app/styleguide/peca/FilterGroup](https://phorte-design-system.vercel.app/styleguide/peca/FilterGroup)
- Ficha no Storybook: [components-complex-filtergroup](https://main--69b4847d498a9bd8659db9ba.chromatic.com/?path=/docs/components-complex-filtergroup--docs)
- Prévia ao vivo, sozinha: [https://phorte-design-system.vercel.app/previa/FilterGroup/0](https://phorte-design-system.vercel.app/previa/FilterGroup/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 { FilterGroup } from '@/app/components/molecules/FilterGroup';

<FilterGroup />
```

## Uso

### Variantes na ficha

1. [Padrão](https://phorte-design-system.vercel.app/previa/FilterGroup/0)
2. [Interativo](https://phorte-design-system.vercel.app/previa/FilterGroup/1)
3. [Múltiplo](https://phorte-design-system.vercel.app/previa/FilterGroup/2)
4. [Com contagem e desabilitada](https://phorte-design-system.vercel.app/previa/FilterGroup/3)

Acima de uma grade ou lista, para trocar entre recortes dela sem sair da página — áreas de curso, categorias do blog. O modo múltiplo, quando os recortes se somam ("Saúde" e "Gestão").

### Quando não usar

Para alternar entre painéis de conteúdo, use o CourseTabs. Para muitos filtros combinados, o CourseFilterSidebar. Num formulário, para escolha única, o Radio.

### Faça

- Dê um `label` que diga o que se filtra ("Áreas do curso"): é o nome do grupo para o leitor.
- Escolha o `modo` pela forma de escolha: `unico` quando só um recorte vale por vez, `multiplo` quando eles se somam — e aí o `selected` é uma lista.
- Deixe uma opção "Todos" como primeira, marcada por padrão, no modo único.
- Separe o que se mostra do que se filtra com `{ valor, rotulo }`: "Negócios" pode filtrar por `negocios`.
- Use `contagem` quando o número ajuda a escolher, e `desabilitado` para o recorte vazio que ainda vale ver.

### Evite

- Muitas opções: além de oito ou dez, a fileira vira rolagem que ninguém vê (a barra de rolagem é escondida).
- Usar para navegar entre páginas: é filtro, não menu.
- Modo único para recortes que se somam: a pessoa tenta marcar dois e perde o primeiro.

### Anatomia

1. **Grupo** — Modo único: `role="radiogroup"`; múltiplo: `role="group"`. O `label` é o nome; rola na horizontal sem barra visível.
2. **Pílula** — Um `<button>`: `role="radio"` com `aria-checked` no modo único, `aria-pressed` no múltiplo. Texto negrito `text-sm`, cantos redondos.
3. **Visto** — Ícone `Check` de 16px antes do rótulo, só na marcada, com `aria-hidden` (o estado já vai no atributo).
4. **Contagem** — Com `contagem`, o número depois do rótulo, em peso médio.

### Estados

| Estado | O que muda |
| --- | --- |
| Marcada | Fundo e borda `--primary`, texto branco e o visto; `aria-checked` (ou `aria-pressed`) `"true"`. |
| Não marcada | Fundo `--card`, texto `--muted-foreground`, borda de controle `--border-interactive`, sem visto. |
| Hover (não marcada) | Fundo `--muted`. |
| Foco | O anel de foco (`anel-de-foco`), só no teclado. |
| Desabilitada | A 50%, cursor proibido, fora do Tab e pulada pelas setas. |

### Comportamento

| Situação | O que acontece |
| --- | --- |
| Escolher no modo único | Chama `onSelect` com o `valor`; quem guarda a escolhida é o consumidor (`selected`). Conferido no teste da ficha: a nova fica com `aria-checked="true"` e a anterior volta a `false`. |
| Com `contagem` | O número entra no nome, separado: "Todas, 42" — conferido no teste da ficha. |
| Escolher no modo múltiplo | Chama `onSelect` com a lista nova — a pílula entra ou sai dela. Conferido no teste da ficha. |

### Relacionados

- [CourseTabs](https://phorte-design-system.vercel.app/styleguide/md/CourseTabs.md) — Para alternar entre painéis.
- [CourseFilterSidebar](https://phorte-design-system.vercel.app/styleguide/md/CourseFilterSidebar.md) — Para filtros combinados.
- [Radio](https://phorte-design-system.vercel.app/styleguide/md/Radio.md) — Escolha única dentro de um formulário.

## Especificação

### Propriedades

| Prop | Tipo | Padrão | Obrigatória | Descrição |
| --- | --- | --- | --- | --- |

Aceita também: `| (Base & { /** Uma opção por vez (padrão): grupo de rádio, com as setas. */ modo?: 'unico'; selected: string; onSelect: (valor: string) => void; }) | (Base & { /** Várias opções juntas: cada pílula alterna, com `aria-pressed`. */ modo: 'multiplo'; selected: string[]; onSelect: (valores: string[]) => void; })`.

### Medidas

| Parte | Valor | Classe |
| --- | --- | --- |
| Altura da pílula | 44px (medido em 1280 e 375) | `min-h-alvo-toque px-4` |
| Visto | 16px | `Check size={16}` |

### Tokens de cor

| Token | Valor | Usado como |
| --- | --- | --- |
| `--primary` | #D42B2B | `bg-primary`, `border-primary` |
| `--border-interactive` | #8C8C8C | `border-border-interactive` |
| `--card` | #FFFFFF | `bg-card` |
| `--muted` | #F4F6F9 | `bg-muted` |
| `--muted-foreground` | #595959 | `text-muted-foreground` |
| `--primary-foreground` | #FFFFFF | `text-primary-foreground` |

## Acessibilidade

### Teclado

| Tecla | Faz |
| --- | --- |
| Tab | Modo único: entra no grupo pela marcada (ou pela primeira) e sai dele no próximo Tab — uma parada só. Múltiplo: cada pílula é uma parada. Conferido no teste da ficha. |
| → / ↓ | Modo único: vai à próxima e a marca, pulando a desabilitada; da última volta à primeira. |
| ← / ↑ | Modo único: vai à anterior e a marca. |
| Home / End | Modo único: vai à primeira ou à última e a marca. |
| Enter / Espaço | Marca a pílula em foco; no modo múltiplo, alterna. |

### Leitor de tela

- O anúncio segue o comportamento (E61): no modo único, "botão de opção, marcado, 2 de 4"; no múltiplo, "botão alternado, pressionado". Antes toda pílula era alternância, e quem ouvia esperava poder desligar a do modo único.
- Estado nunca só por cor: a marcada ganha o visto além do vermelho.

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