# Datepicker

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

Componente completo de seleção de datas com campo de input e painel flutuante. Substituto direto do `p-datepicker` do PrimeNG, com API moderna baseada em Angular Signals e posicionamento nativo via CDK Overlay.

## Quando usar

- Formulários que exigem seleção de data, hora ou intervalo de datas
- Filtros de período com seleção de data de início e fim (`mode="range"`)
- Campos de hora isolados sem calendário (`mode="time"`)
- Seleção de competência (mês/ano) sem necessidade de escolher o dia (`mode="month"`)

## Quando não usar

- Para exibir datas sem interação — use `DatePipe` do Angular diretamente
- Para seleção de múltiplas datas avulsas — este componente não suporta `selectionMode="multiple"`
- Quando o campo está dentro de um modal e o painel precisa escapar do `overflow: hidden` — o CDK Overlay já trata isso nativamente; não é necessário configuração extra

## Instalação

```typescript
import { DatepickerComponent } from '@seniorsistemas/angular-components/datepicker';

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

## Uso básico

```html
<s-datepicker [formControl]="dataCtrl" mode="date" />
```

## API

### Inputs

| Propriedade | Tipo | Padrão | Obrigatório | Descrição |
|---|---|---|:-----------:|---|
| `inputId` | `string` | auto-gerado | Não | HTML `id` aplicado ao elemento `<input>`. |
| `name` | `string` | `undefined` | Não | Atributo `name` do `<input>` nativo. |
| `placeholder` | `string` | `undefined` | Não | Texto exibido quando nenhum valor está selecionado. |
| `mode` | `DatePickerMode` | `'date'` | Não | Modo de seleção do componente. Ver tabela de modos abaixo. |
| `showIcon` | `boolean` | `true` | Não | Exibe o botão de ícone ao lado do campo. |
| `icon` | `string` | `'fas fa-calendar'` | Não | Classe CSS do ícone. No modo `time`, usa `'fas fa-clock'` automaticamente. |
| `showOnFocus` | `boolean` | `false` | Não | Abre o painel ao focar o campo. |
| `min` | `Date \| null` | `null` | Não | Data mínima selecionável. Dias anteriores ficam desabilitados. |
| `max` | `Date \| null` | `null` | Não | Data máxima selecionável. Dias posteriores ficam desabilitados. |
| `defaultDate` | `Date \| null` | `null` | Não | Data exibida ao abrir o painel quando nenhuma data está selecionada. |
| `dateFormat` | `string` | `'dd/MM/yyyy'` | Não | Formato de exibição da data no campo. |
| `hourFormat` | `'12' \| '24'` | `'24'` | Não | Formato de exibição das horas. |
| `minuteStep` | `number` | `5` | Não | Incremento em minutos ao usar as setas do time picker. |
| `showSeconds` | `boolean` | `false` | Não | Exibe o campo de segundos no time picker. |
| `rangeSeparator` | `string` | `' — '` | Não | Separador exibido entre as datas no modo `range`. |
| `disabled` | `boolean` | `false` | Não | Desabilita o componente (model two-way). |

### Outputs

| Evento | Tipo emitido | Descrição |
|---|---|---|
| `blur` | `Event` | Emitido quando o campo perde o foco. |
| `focus` | `Event` | Emitido quando o campo recebe o foco. |
| `select` | `Date \| DateRange \| null` | Emitido ao selecionar uma data, mês, horário ou intervalo. |
| `close` | `void` | Emitido quando o painel do calendário fecha. |
| `todayClick` | `Date` | Emitido ao clicar no botão "Hoje". |
| `clearClick` | `void` | Emitido ao clicar no botão "Limpar". |
| `monthChange` | `{ month: number; year: number }` | Emitido quando o mês visualizado muda. |
| `yearChange` | `{ month: number; year: number }` | Emitido quando o ano visualizado muda. |

### Tipos

```typescript
type DatePickerMode = 'date' | 'month' | 'datetime' | 'time' | 'range';

interface DateRange {
  start: Date | null;
  end: Date | null;
}
```

### Modos (`DatePickerMode`)

| Modo | Valor emitido | Descrição |
|---|---|---|
| `date` | `Date` | Calendário com seleção de dia (padrão). |
| `month` | `Date` | Seleção de mês e ano — o `Date` emitido aponta para o primeiro dia do mês. |
| `datetime` | `Date` | Calendário + time picker. O painel só fecha ao clicar em "Confirmar". |
| `time` | `Date` | Apenas seletor de hora, sem calendário. |
| `range` | `DateRange` | Seleção de intervalo com data de início e fim. |

## Exemplos

### Com `formControl`

```html
<s-datepicker [formControl]="dataCtrl" mode="date" />
```

```typescript
dataCtrl = new FormControl<Date | null>(null, Validators.required);
```

### Com `ngModel`

```html
<s-datepicker [(ngModel)]="dataSelecionada" mode="datetime" />
```

### Data e hora

```html
<s-datepicker [formControl]="ctrl" mode="datetime" [minuteStep]="15" [showSeconds]="true" />
```

### Intervalo de datas

```html
<s-datepicker [formControl]="periodoCtrl" mode="range" rangeSeparator=" até " />
```

```typescript
periodoCtrl = new FormControl<DateRange | null>(null);
```

### Com limites de data

```html
<s-datepicker [formControl]="ctrl" mode="date" [min]="dataMinima" [max]="dataMaxima" />
```

### Seleção de mês

```html
<s-datepicker [formControl]="competenciaCtrl" mode="month" placeholder="Selecione a competência" />
```

### Apenas hora

```html
<s-datepicker [formControl]="horaCtrl" mode="time" [minuteStep]="1" [showSeconds]="true" />
```

### Com Dynamic Form

```typescript
const config: CalendarFieldConfig = {
  type: 'date',
  name: 'dataNascimento',
  label: 'Data de nascimento',
};
```

```html
<s-dynamic-form [config]="config" />
```

## Acessibilidade

- O trigger usa `role="combobox"` com `aria-haspopup="grid"`, `aria-expanded` e `aria-controls` apontando para o painel
- O painel usa `role="dialog"` com `aria-label` traduzido e `cdkTrapFocus` para prender o foco dentro do popup
- Ao abrir o painel, o foco é movido automaticamente para o primeiro botão do calendário ou para o botão de incremento de horas no modo `time`
- Ao fechar o painel, o foco retorna ao botão de ícone do input trigger
- Tecla `Escape` fecha o painel e devolve o foco ao trigger
- Dias do calendário usam `role="gridcell"` com `aria-label` contendo a data por extenso, `aria-selected` e `aria-disabled`
- Cabeçalhos dos dias da semana usam `role="columnheader"` com `aria-label`
- Setas do time picker têm `aria-label` descritivos; as horas/minutos têm `aria-live="polite"`
- Todos os ícones decorativos têm `aria-hidden="true"`

## Componentes relacionados

- [`DynamicFormComponent`](../../src/lib/dynamic-form/README.md) — usa `s-datepicker` internamente para campos do tipo `date`, `time`, `dateTime` e `localDateTime`
