# RatingScale

![Status](https://img.shields.io/badge/status-stable-brightgreen)

Componente de escala de avaliação que permite ao usuário selecionar um nó de uma escala visual. Ideal para pesquisas de satisfação (NPS, CSAT) e questionários de feedback. Implementa `ControlValueAccessor` para integração com Reactive Forms e Template-Driven Forms.

## Quando usar

- Pesquisas de satisfação com representação visual emocional (ícones de humor)
- Net Promoter Score (NPS) com escala numérica de 0 a 10
- Avaliação de atendimento, suporte ou experiência do usuário
- Formulários de feedback com escalas qualitativas ou quantitativas

## Quando não usar

- Para avaliações com estrelas — use `StarRating`
- Para seleção de uma opção de um conjunto sem representação visual de escala — use `RadioButtonGroup`
- Quando a escala tem mais de 15 itens e o espaço horizontal é limitado

## Instalação

```typescript
import { RatingScaleModule } from '@seniorsistemas/angular-components/rating-scale';

@NgModule({ imports: [RatingScaleModule] })
export class MeuModulo {}
```

## Uso básico

```html
<s-rating-scale
  [nodes]="nosAvaliacao"
  startLabel="Insatisfeito"
  endLabel="Satisfeito"
  [(ngModel)]="avaliacaoSelecionada"
/>
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `nodes` | `RatingScaleNode[]` | — | Sim | Lista de nós que compõem a escala. Cada nó é uma opção clicável |
| `startLabel` | `string` | `undefined` | Não | Rótulo exibido abaixo do primeiro nó (extremo negativo) |
| `endLabel` | `string` | `undefined` | Não | Rótulo exibido abaixo do último nó (extremo positivo) |
| `disabled` | `boolean` | `false` | Não | Desabilita o componente, impedindo seleção de qualquer nó |

### Tipos

```typescript
interface RatingScaleNode {
  id: string;             // Identificador único do nó (obrigatório)
  title?: string;         // Texto exibido abaixo do ícone
  /** @deprecated Use `selectedIcon` e `unselectedIcon`. */
  icon?: string;           // Classe do ícone Font Awesome sem o glifo (ex: 'fa-smile') — sempre exibido com o glifo fixo `fas`
  selectedIcon?: string;   // Classe completa (glifo + ícone, ex: 'fas fa-smile') exibida quando o nó está selecionado
  unselectedIcon?: string; // Classe completa (glifo + ícone, ex: 'far fa-smile') exibida quando o nó não está selecionado
}
```

> O `FormControl` deve ser do tipo `RatingScaleNode`. O componente emite o objeto `RatingScaleNode` completo quando um nó é selecionado.

> **`selectedIcon`/`unselectedIcon` devem ser informados juntos.** Se apenas um dos dois for informado, o componente emite um aviso no console e não exibe nenhum ícone para aquele nó. Se os dois forem informados, eles têm prioridade sobre `icon` (que é ignorado nesse caso).

## Exemplos

### Escala de humor com ícones

```typescript
const nosHumor: RatingScaleNode[] = [
  { id: 'very-happy', title: 'Muito feliz', selectedIcon: 'fas fa-laugh-wink', unselectedIcon: 'far fa-laugh-wink' },
  { id: 'happy', title: 'Feliz', selectedIcon: 'fas fa-smile', unselectedIcon: 'far fa-smile' },
  { id: 'normal', title: 'Normal', selectedIcon: 'fas fa-meh', unselectedIcon: 'far fa-meh' },
  { id: 'sad', title: 'Triste', selectedIcon: 'fas fa-sad-tear', unselectedIcon: 'far fa-sad-tear' },
  { id: 'very-sad', title: 'Muito triste', selectedIcon: 'fas fa-sad-cry', unselectedIcon: 'far fa-sad-cry' },
];
```

```html
<form [formGroup]="form">
  <s-rating-scale
    formControlName="avaliacao"
    [nodes]="nosHumor"
    startLabel="Triste"
    endLabel="Feliz"
  ></s-rating-scale>
</form>
```

### Escala numérica NPS (1 a 10)

```typescript
const nosNPS: RatingScaleNode[] = Array.from({ length: 10 }, (_, i) => ({
  id: String(i + 1),
  title: String(i + 1),
}));
```

```html
<s-rating-scale
  formControlName="nps"
  [nodes]="nosNPS"
  startLabel="Muito insatisfeito"
  endLabel="Muito satisfeito"
></s-rating-scale>
```

### Com valor pré-selecionado

```typescript
this.form = new FormGroup({
  avaliacao: new FormControl(nosHumor[1]), // 'Feliz' pré-selecionado
});
```

### Desabilitado (somente leitura)

```html
<s-rating-scale
  formControlName="avaliacao"
  [nodes]="nosHumor"
  [disabled]="true"
  startLabel="Triste"
  endLabel="Feliz"
></s-rating-scale>
```

### Apenas ícones (sem títulos nos nós)

```html
<s-rating-scale
  [nodes]="[
    { id: 'very-happy', selectedIcon: 'fas fa-laugh-wink', unselectedIcon: 'far fa-laugh-wink' },
    { id: 'happy', selectedIcon: 'fas fa-smile', unselectedIcon: 'far fa-smile' },
    { id: 'normal', selectedIcon: 'fas fa-meh', unselectedIcon: 'far fa-meh' },
    { id: 'sad', selectedIcon: 'fas fa-sad-tear', unselectedIcon: 'far fa-sad-tear' },
    { id: 'very-sad', selectedIcon: 'fas fa-sad-cry', unselectedIcon: 'far fa-sad-cry' }
  ]"
  startLabel="Triste"
  endLabel="Feliz"
  [(ngModel)]="avaliacao"
></s-rating-scale>
```

## Acessibilidade

- Cada nó é um elemento `<button>` nativo, navegável por `Tab`, `Enter` e `Space`
- O nó selecionado recebe destaque visual
- Os ícones requerem Font Awesome disponível na aplicação
- `startLabel` e `endLabel` contextualizam os extremos da escala para todos os usuários
- Em modo `disabled`, nenhum nó aceita interação e o estilo visual indica o estado inativo

## Migração

### `icon` para `selectedIcon`/`unselectedIcon`

O campo `icon` de `RatingScaleNode` está depreciado. Ele sempre exibia o ícone com o glifo `fas` fixo, independente do nó estar selecionado ou não. Os novos campos `selectedIcon`/`unselectedIcon` recebem a classe completa (glifo + ícone) pra cada estado, permitindo escolher livremente qualquer combinação — inclusive estilos diferentes (`fas`/`far`/etc.) por nó:

```typescript
// Antes
const nos: RatingScaleNode[] = [
  { id: 'happy', title: 'Feliz', icon: 'fa-smile' },
];

// Depois
const nos: RatingScaleNode[] = [
  { id: 'happy', title: 'Feliz', selectedIcon: 'fas fa-smile', unselectedIcon: 'far fa-smile' },
];
```

`selectedIcon` e `unselectedIcon` devem ser informados sempre em conjunto — informar só um dos dois gera um aviso no console e nenhum ícone é exibido para o nó.

## Componentes relacionados

- [`StarRating`](../star-rating/README.md) — avaliação por estrelas com escala numérica fixa
- [`RadioButton`](../radio-button/README.md) — seleção única em lista de opções
