# PinCodeField

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

Componente para entrada de códigos PIN ou códigos de verificação (OTP) com campos individuais para cada dígito. Implementa `ControlValueAccessor` para integração nativa com Reactive Forms e Template-Driven Forms do Angular.

## Quando usar

- Códigos de verificação OTP enviados por SMS ou e-mail
- Autenticação de dois fatores (2FA)
- PINs numéricos de acesso (ex: cartão de crédito)
- Códigos de ativação de produto (alfanumérico)

## Quando não usar

- Para senhas textuais sem comprimento fixo — use `<input type="password">` com `sPasswordStrength`
- Para campos de texto curto com comprimento variável — use `InputText`

## Instalação

```typescript
import { PinCodeFieldComponent } from '@seniorsistemas/angular-components/pin-code-field';

@Component({
  standalone: true,
  imports: [PinCodeFieldComponent, ReactiveFormsModule],
})
export class MeuComponent {}
```

## Uso básico

```html
<form [formGroup]="form">
  <s-pin-code-field
    formControlName="codigo"
    [length]="6"
    helpText="Digite o código de 6 dígitos recebido"
    (codeFilled)="onCodigoConcluido($event)"
  ></s-pin-code-field>
</form>
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|-------------|------|--------|:-----------:|-----------|
| `length` | `number` | `6` | Não | Número de campos de entrada (comprimento do código PIN). Mínimo: 1 |
| `alphanumeric` | `boolean` | `false` | Não | Permite entrada alfanumérica. Quando `false`, aceita apenas dígitos (0–9) |
| `helpText` | `string` | `''` | Não | Texto de ajuda exibido abaixo dos campos |
| `invalid` | `boolean` | `false` | Não | Exibe borda vermelha nos campos. Tipicamente vinculado ao estado `invalid && dirty` do `FormControl` |
| `disabled` | `boolean` | `false` | Não | Two-way binding para o estado desabilitado. Desabilita todos os campos |

### Outputs

| Evento | Tipo | Descrição |
|--------|------|-----------|
| `codeFilled` | `OutputEmitterRef<string>` | Emitido quando todos os campos estão preenchidos. Emite o código completo como string |

## Exemplos

### Código OTP de 6 dígitos com Reactive Forms

```html
<form [formGroup]="form">
  <s-pin-code-field
    formControlName="codigo"
    [length]="6"
    [alphanumeric]="false"
    [invalid]="(form.get('codigo')?.invalid && form.get('codigo')?.dirty) || false"
    helpText="Digite o código de 6 dígitos recebido"
    (codeFilled)="onCodigoConcluido($event)"
  ></s-pin-code-field>
</form>
```

### PIN de 4 dígitos

```html
<s-pin-code-field
  formControlName="pin"
  [length]="4"
  helpText="Digite seu PIN de 4 dígitos"
></s-pin-code-field>
```

### Código alfanumérico

```html
<s-pin-code-field
  formControlName="chave"
  [length]="6"
  [alphanumeric]="true"
  helpText="Digite o código alfanumérico (letras e números)"
></s-pin-code-field>
```

### Estado de erro

```html
<s-pin-code-field
  formControlName="codigo"
  [length]="6"
  [invalid]="true"
  helpText="Digite o código de 6 dígitos"
></s-pin-code-field>
<p style="color: red;">Código inválido. Tente novamente.</p>
```

### Desabilitado com valor pré-preenchido

```typescript
this.form = new FormGroup({
  codigo: new FormControl('123456'),
});
this.form.disable();
```

```html
<s-pin-code-field formControlName="codigo" [length]="6"></s-pin-code-field>
```

## Acessibilidade

- Cada campo de entrada possui ARIA label e role semântico correto
- Navegação completa por teclado:
  - `ArrowRight` / `ArrowLeft`: move o foco entre os campos
  - `Backspace`: limpa o campo atual ou retorna ao anterior
  - Auto-avança para o próximo campo ao preencher cada dígito
- Suporte a colar (Ctrl+V / Cmd+V): distribui automaticamente os caracteres válidos entre os campos
- O componente é marcado como `touched` quando o último campo perde o foco

## Componentes relacionados

- [`PasswordStrength`](../password-strength/README.md) — indicador visual de força de senha
