# tmw-picker — Guida d'uso e casi pratici

Raccolta di esempi pronti all'uso per implementare rapidamente i componenti di
`tmw-picker`. Per la panoramica delle API vedi il [README](./README.md); per i
breaking changes rispetto alla 1.0.x la [MIGRATION.md](./MIGRATION.md).

## Indice

1. [Setup del progetto](#1-setup-del-progetto)
2. [Concetti base: `pickerMode` e `timeType`](#2-concetti-base-pickermode-e-timetype)
3. [Date picker in Reactive Form](#3-date-picker-in-reactive-form)
4. [Date picker template-driven (`ngModel`)](#4-date-picker-template-driven-ngmodel)
5. [Date + ora con step](#5-data--ora-con-step)
6. [Time picker](#6-time-picker)
7. [Data di nascita (birth picker)](#7-data-di-nascita-birth-picker)
8. [Time stepper](#8-time-stepper)
9. [Selettore di intervallo (da–a)](#9-selettore-di-intervallo-dataa)
10. [Selettore a lista di stringhe](#10-selettore-a-lista-di-stringhe)
11. [Validazione e messaggi di errore](#11-validazione-e-messaggi-di-errore)
12. [Output: stringa, Date o DateTime](#12-output-stringa-date-o-datetime)
13. [Timezone e salvataggio a DB](#13-timezone-e-salvataggio-a-db)
14. [Localizzazione (i18n)](#14-localizzazione-i18n)
15. [Date evidenziate, min/max, disabled](#15-date-evidenziate-minmax-disabled)

---

## 1. Setup del progetto

Installa la libreria e le peer dependencies:

```bash
npm i tmw-picker luxon
```

I componenti sono **standalone**, non hanno dipendenza da Angular Material/CDK
e includono già al loro interno tutta la logica di calendario (Luxon-based,
nessun `DateAdapter` da configurare). Ti serve solo importarli dove servono e
— per i form — i moduli dei form.

### App standalone (`bootstrapApplication`)

```ts
// un componente standalone consumatore
import { Component } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { TmwDateTimePickerComponent, ModeEnum, TimeTypeEnum } from 'tmw-picker';

@Component({
  selector: 'app-esempio',
  standalone: true,
  imports: [ReactiveFormsModule, TmwDateTimePickerComponent],
  templateUrl: './esempio.component.html',
})
export class EsempioComponent {
  mode = ModeEnum;
  type = TimeTypeEnum;
}
```

### App basata su NgModule

```ts
import { ReactiveFormsModule, FormsModule } from '@angular/forms';
import { TmwDateTimePickerComponent, TmwDateRangePickerComponent, TmwPickerComponent } from 'tmw-picker';

@NgModule({
  imports: [
    ReactiveFormsModule,
    FormsModule,
    // i componenti standalone vanno negli imports, non in declarations
    TmwDateTimePickerComponent,
    TmwDateRangePickerComponent,
    TmwPickerComponent,
  ],
})
export class AppModule {}
```

---

## 2. Concetti base: `pickerMode` e `timeType`

`tmw-datetimepicker` è **un solo componente polimorfico**: cambia
comportamento in base a `pickerMode`.

```ts
import { ModeEnum, TimeTypeEnum } from 'tmw-picker';

ModeEnum.DATEPICKER         // solo data
ModeEnum.DATETIMEPICKER     // data + ora
ModeEnum.TIMEPICKER         // solo ora (dialog a liste)
ModeEnum.BIRTHPICKER        // data di nascita (giorno/mese/anno a liste)
ModeEnum.TIMESTEPPERPICKER  // ora a step fissi
ModeEnum.DATERANGEPICKER    // (usa il componente tmw-daterangepicker)
```

`timeType` decide **il tipo del valore** emesso al form:

```ts
TimeTypeEnum.DATE    // -> Date JS
TimeTypeEnum.STRING  // -> stringa formattata con outputFormat
TimeTypeEnum.MOMENT  // -> oggetto Luxon DateTime
```

> I formati (`inputFormat`/`outputFormat`) usano i **token Luxon**:
> `dd/MM/yyyy`, `yyyy-MM-dd HH:mm:ss`, `HH:mm`, ecc.

---

## 3. Date picker in Reactive Form

```ts
export class FormComponent {
  mode = ModeEnum;
  type = TimeTypeEnum;

  form = new FormGroup({
    dataEvento: new FormControl<Date | null>(null, Validators.required),
  });

  salva() {
    if (this.form.valid) {
      console.log(this.form.value.dataEvento); // Date
    }
  }
}
```

```html
<form [formGroup]="form" (ngSubmit)="salva()">
  <tmw-datetimepicker
    formControlName="dataEvento"
    [pickerMode]="mode.DATEPICKER"
    [timeType]="type.DATE"
    [inputFormat]="'dd/MM/yyyy'"
    [outputFormat]="'dd/MM/yyyy'"
    label="Data evento">
  </tmw-datetimepicker>

  <button type="submit" [disabled]="form.invalid">Salva</button>
</form>
```

---

## 4. Date picker template-driven (`ngModel`)

```ts
export class NgModelComponent {
  mode = ModeEnum;
  type = TimeTypeEnum;
  data: string | null = null;
}
```

```html
<tmw-datetimepicker
  [(ngModel)]="data"
  [pickerMode]="mode.DATEPICKER"
  [timeType]="type.STRING"
  [outputFormat]="'yyyy-MM-dd'"
  (dateChange)="onChange($event)">
</tmw-datetimepicker>

<p>Valore: {{ data }}</p>
```

---

## 5. Data + ora con step

L'orario si imposta da un pulsante dedicato (dialog a liste) accanto al
calendario. Gli step limitano i valori selezionabili.

```html
<tmw-datetimepicker
  formControlName="appuntamento"
  [pickerMode]="mode.DATETIMEPICKER"
  [timeType]="type.DATE"
  [outputFormat]="'dd/MM/yyyy HH:mm'"
  [showHours]="true"
  [showMinutes]="true"
  [showSeconds]="false"
  [stepMinute]="15"
  label="Appuntamento">
</tmw-datetimepicker>
```

In questo esempio i minuti sono selezionabili solo a passi di 15 (00, 15, 30, 45)
e i secondi sono nascosti.

---

## 6. Time picker

```html
<tmw-datetimepicker
  formControlName="orario"
  [pickerMode]="mode.TIMEPICKER"
  [timeType]="type.STRING"
  [inputFormat]="'HH:mm'"
  [outputFormat]="'HH:mm'"
  [showHours]="true"
  [showMinutes]="true"
  [showSeconds]="false"
  [stepMinute]="5"
  hourLabel="Ore"
  minuteLabel="Minuti"
  label="Orario">
</tmw-datetimepicker>
```

---

## 7. Data di nascita (birth picker)

Giorno/mese/anno selezionabili da liste. `minDate`/`maxDate` limitano gli anni
proposti.

```ts
export class BirthComponent {
  mode = ModeEnum;
  type = TimeTypeEnum;
  minNascita = new Date(1920, 0, 1);
  maxNascita = new Date(); // oggi
}
```

```html
<tmw-datetimepicker
  formControlName="dataNascita"
  [pickerMode]="mode.BIRTHPICKER"
  [timeType]="type.DATE"
  [outputFormat]="'dd/MM/yyyy'"
  [minDate]="minNascita"
  [maxDate]="maxNascita"
  dayLabel="Giorno"
  monthLabel="Mese"
  yearLabel="Anno"
  label="Data di nascita">
</tmw-datetimepicker>
```

---

## 8. Time stepper

Lista di orari generata a intervalli fissi (es. ogni 30 minuti) tra `minDate` e
`maxDate`.

```html
<tmw-datetimepicker
  formControlName="slot"
  [pickerMode]="mode.TIMESTEPPERPICKER"
  [timeType]="type.STRING"
  [outputFormat]="'HH:mm'"
  [stepHour]="0"
  [stepMinute]="30"
  [showSeconds]="false"
  label="Fascia oraria">
</tmw-datetimepicker>
```

---

## 9. Selettore di intervallo (da–a)

Componente dedicato `tmw-daterangepicker`. Il valore è un oggetto
`{ start, end }` (tipo dei membri secondo `timeType`).

```ts
import { TmwDateRange } from 'tmw-picker';

export class RangeComponent {
  type = TimeTypeEnum;
  form = new FormGroup({
    periodo: new FormControl<TmwDateRange | null>(null),
  });

  onRange(r: TmwDateRange) {
    console.log(r.start, r.end);
  }
}
```

```html
<form [formGroup]="form">
  <tmw-daterangepicker
    formControlName="periodo"
    [timeType]="type.DATE"
    [outputFormat]="'yyyy-MM-dd'"
    label="Periodo"
    startPlaceholder="Dal"
    endPlaceholder="Al"
    (rangeChange)="onRange($event)">
  </tmw-daterangepicker>
</form>
```

---

## 10. Selettore a lista di stringhe

`tmw-picker` non è legato alle date: è una listbox accessibile per scegliere un
valore da un elenco.

```ts
export class ListaComponent {
  reparti = ['Cardiologia', 'Radiologia', 'Pediatria', 'Ortopedia'];
  selezionato = 'Radiologia';
}
```

```html
<tmw-picker
  title="Reparto"
  [values]="reparti"
  [selectedValue]="selezionato"
  (onSelectedValue)="selezionato = $event">
</tmw-picker>
```

> Navigazione da tastiera: frecce per spostarsi, Home/End per inizio/fine,
> Invio/Spazio per selezionare.

---

## 11. Validazione e messaggi di errore

Il componente implementa `Validator`: gli errori finiscono direttamente sul
`FormControl`.

| Errore | Quando |
|--------|--------|
| `tmwInvalidDate` | formato non valido |
| `matDatepickerMin` | data prima di `minDate` |
| `matDatepickerMax` | data dopo `maxDate` |
| `tmwRangeInvalid` | (range) `end` precede `start` |

```html
<tmw-datetimepicker
  formControlName="data"
  [pickerMode]="mode.DATEPICKER"
  [timeType]="type.DATE"
  [minDate]="oggi"
  label="Data (non passata)">
</tmw-datetimepicker>

<div class="errore" *ngIf="form.get('data')?.hasError('matDatepickerMin')">
  La data non può essere nel passato.
</div>
<div class="errore" *ngIf="form.get('data')?.hasError('tmwInvalidDate')">
  Formato data non valido.
</div>
```

---

## 12. Output: stringa, Date o DateTime

Lo stesso input può produrre tipi diversi in base a `timeType`:

```html
<!-- emette una Date JS -->
<tmw-datetimepicker formControlName="d1" [timeType]="type.DATE"
  [pickerMode]="mode.DATEPICKER"></tmw-datetimepicker>

<!-- emette "2026-06-11" (stringa) -->
<tmw-datetimepicker formControlName="d2" [timeType]="type.STRING"
  [outputFormat]="'yyyy-MM-dd'" [pickerMode]="mode.DATEPICKER"></tmw-datetimepicker>

<!-- emette un Luxon DateTime -->
<tmw-datetimepicker formControlName="d3" [timeType]="type.MOMENT"
  [pickerMode]="mode.DATEPICKER"></tmw-datetimepicker>
```

```ts
// con timeType MOMENT puoi usare l'API Luxon sul valore
const dt = this.form.value.d3 as DateTime;
console.log(dt.toISO(), dt.weekdayLong);
```

---

## 13. Timezone e salvataggio a DB

**Caso A — salvare l'orario "da calendario" senza shift di fuso.**
`forSaveLocalOnDB` emette una `Date` i cui campi UTC coincidono con l'orario
mostrato (utile quando il backend salva in UTC ma vuoi conservare l'ora locale
inserita dall'utente).

```html
<tmw-datetimepicker
  formControlName="inizioTurno"
  [pickerMode]="mode.DATETIMEPICKER"
  [timeType]="type.DATE"
  [forSaveLocalOnDB]="true">
</tmw-datetimepicker>
```

**Caso B — interpretare l'orario in un fuso specifico (IANA).**

```html
<tmw-datetimepicker
  formControlName="meeting"
  [pickerMode]="mode.DATETIMEPICKER"
  [timeType]="type.MOMENT"
  [timeZone]="'Europe/Rome'">
</tmw-datetimepicker>
```

> `timeZone` ha precedenza su `forSaveLocalOnDB`.

---

## 14. Localizzazione (i18n)

`locale` pilota i nomi di mesi e giorni del calendario.

```html
<tmw-datetimepicker
  formControlName="data"
  [pickerMode]="mode.DATEPICKER"
  [locale]="'en-US'">
</tmw-datetimepicker>
```

---

## 15. Date evidenziate, min/max, disabled

```ts
export class EvidenziateComponent {
  oggi = new Date();
  traUnMese = new Date(Date.now() + 30 * 86400000);
  festivi = [new Date(2026, 11, 25), new Date(2026, 11, 26)];
}
```

```html
<tmw-datetimepicker
  formControlName="data"
  [pickerMode]="mode.DATEPICKER"
  [minDate]="oggi"
  [maxDate]="traUnMese"
  [highLightedDates]="festivi"
  [disabled]="false"
  [readonly]="false">
</tmw-datetimepicker>
```

Le date in `highLightedDates` ricevono la classe CSS
`datetimepicker-highlighted-date`, personalizzabile via stile globale:

```scss
.datetimepicker-highlighted-date {
  background-color: #ffe082;
  border-radius: 50%;
}
```

---

## Debug

`[debugMode]="true"` stampa in console il flusso di trasformazione delle date —
utile per capire come un input viene parsato ed emesso.

```html
<tmw-datetimepicker [debugMode]="true" formControlName="data"
  [pickerMode]="mode.DATEPICKER"></tmw-datetimepicker>
```
