@oneluiz/dual-datepicker 2.4.0 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,9 +1,129 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, signal, computed, effect, forwardRef, HostListener, Output, Input, Component } from '@angular/core';
2
+ import { InjectionToken, Injectable, EventEmitter, inject, signal, computed, effect, forwardRef, HostListener, Output, Input, Component } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
5
  import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
6
6
 
7
+ /**
8
+ * Abstract class for date adapters.
9
+ * Allows the component to work with different date libraries (Date, DayJS, date-fns, Luxon, etc.)
10
+ */
11
+ class DateAdapter {
12
+ }
13
+ /**
14
+ * Injection token for DateAdapter
15
+ */
16
+ const DATE_ADAPTER = new InjectionToken('DATE_ADAPTER');
17
+
18
+ /**
19
+ * Date adapter implementation for native JavaScript Date objects
20
+ * This is the default adapter used by the component
21
+ */
22
+ class NativeDateAdapter extends DateAdapter {
23
+ parse(value) {
24
+ if (!value)
25
+ return null;
26
+ if (value instanceof Date) {
27
+ return new Date(value);
28
+ }
29
+ if (typeof value === 'string' || typeof value === 'number') {
30
+ const date = new Date(value);
31
+ return this.isValid(date) ? date : null;
32
+ }
33
+ return null;
34
+ }
35
+ format(date, format = 'YYYY-MM-DD') {
36
+ if (!this.isValid(date))
37
+ return '';
38
+ const year = date.getFullYear();
39
+ const month = String(date.getMonth() + 1).padStart(2, '0');
40
+ const day = String(date.getDate()).padStart(2, '0');
41
+ // Simple format implementation
42
+ switch (format) {
43
+ case 'YYYY-MM-DD':
44
+ return `${year}-${month}-${day}`;
45
+ case 'MM/DD/YYYY':
46
+ return `${month}/${day}/${year}`;
47
+ case 'DD/MM/YYYY':
48
+ return `${day}/${month}/${year}`;
49
+ default:
50
+ return `${year}-${month}-${day}`;
51
+ }
52
+ }
53
+ addDays(date, days) {
54
+ const result = this.clone(date);
55
+ result.setDate(result.getDate() + days);
56
+ return result;
57
+ }
58
+ addMonths(date, months) {
59
+ const result = this.clone(date);
60
+ result.setMonth(result.getMonth() + months);
61
+ return result;
62
+ }
63
+ getYear(date) {
64
+ return date.getFullYear();
65
+ }
66
+ getMonth(date) {
67
+ return date.getMonth();
68
+ }
69
+ getDate(date) {
70
+ return date.getDate();
71
+ }
72
+ getDay(date) {
73
+ return date.getDay();
74
+ }
75
+ createDate(year, month, date) {
76
+ return new Date(year, month, date);
77
+ }
78
+ today() {
79
+ return new Date();
80
+ }
81
+ isSameDay(a, b) {
82
+ if (!a || !b)
83
+ return false;
84
+ if (!this.isValid(a) || !this.isValid(b))
85
+ return false;
86
+ return (a.getFullYear() === b.getFullYear() &&
87
+ a.getMonth() === b.getMonth() &&
88
+ a.getDate() === b.getDate());
89
+ }
90
+ isBefore(a, b) {
91
+ if (!a || !b)
92
+ return false;
93
+ if (!this.isValid(a) || !this.isValid(b))
94
+ return false;
95
+ return a.getTime() < b.getTime();
96
+ }
97
+ isAfter(a, b) {
98
+ if (!a || !b)
99
+ return false;
100
+ if (!this.isValid(a) || !this.isValid(b))
101
+ return false;
102
+ return a.getTime() > b.getTime();
103
+ }
104
+ isBetween(date, start, end) {
105
+ if (!date || !start || !end)
106
+ return false;
107
+ if (!this.isValid(date) || !this.isValid(start) || !this.isValid(end))
108
+ return false;
109
+ const dateTime = date.getTime();
110
+ const startTime = start.getTime();
111
+ const endTime = end.getTime();
112
+ return dateTime >= startTime && dateTime <= endTime;
113
+ }
114
+ clone(date) {
115
+ return new Date(date.getTime());
116
+ }
117
+ isValid(date) {
118
+ return date instanceof Date && !isNaN(date.getTime());
119
+ }
120
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter, deps: null, target: i0.ɵɵFactoryTarget.Injectable });
121
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter });
122
+ }
123
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: NativeDateAdapter, decorators: [{
124
+ type: Injectable
125
+ }] });
126
+
7
127
  class DualDatepickerComponent {
8
128
  elementRef;
9
129
  placeholder = 'Select date range';
@@ -28,12 +148,14 @@ class DualDatepickerComponent {
28
148
  locale = {};
29
149
  dateRangeChange = new EventEmitter();
30
150
  dateRangeSelected = new EventEmitter();
151
+ // Date adapter injection
152
+ dateAdapter = inject(DATE_ADAPTER);
31
153
  // Signals for reactive state
32
154
  mostrarDatePicker = signal(false);
33
155
  rangoFechas = signal('');
34
156
  fechaSeleccionandoInicio = signal(true);
35
- mesActual = signal(new Date());
36
- mesAnterior = signal(new Date());
157
+ mesActual = signal(this.dateAdapter.today());
158
+ mesAnterior = signal(this.dateAdapter.today());
37
159
  diasMesActual = signal([]);
38
160
  diasMesAnterior = signal([]);
39
161
  isDisabled = signal(false);
@@ -84,17 +206,19 @@ class DualDatepickerComponent {
84
206
  }
85
207
  }
86
208
  formatearFecha(fecha) {
87
- const year = fecha.getFullYear();
88
- const month = String(fecha.getMonth() + 1).padStart(2, '0');
89
- const day = String(fecha.getDate()).padStart(2, '0');
209
+ const year = this.dateAdapter.getYear(fecha);
210
+ const month = String(this.dateAdapter.getMonth(fecha) + 1).padStart(2, '0');
211
+ const day = String(this.dateAdapter.getDate(fecha)).padStart(2, '0');
90
212
  return `${year}-${month}-${day}`;
91
213
  }
92
214
  formatearFechaDisplay(fechaStr) {
93
215
  if (!fechaStr)
94
216
  return '';
95
- const fecha = new Date(fechaStr + 'T00:00:00');
217
+ const fecha = this.dateAdapter.parse(fechaStr);
218
+ if (!fecha)
219
+ return '';
96
220
  const monthNames = this.locale.monthNamesShort || this.defaultMonthNamesShort;
97
- return `${fecha.getDate()} ${monthNames[fecha.getMonth()]}`;
221
+ return `${this.dateAdapter.getDate(fecha)} ${monthNames[this.dateAdapter.getMonth(fecha)]}`;
98
222
  }
99
223
  actualizarRangoFechasTexto() {
100
224
  if (this.fechaInicio && this.fechaFin) {
@@ -111,7 +235,10 @@ class DualDatepickerComponent {
111
235
  if (this.mostrarDatePicker()) {
112
236
  this.fechaSeleccionandoInicio.set(true);
113
237
  const mesActualValue = this.mesActual();
114
- this.mesAnterior.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() - 1, 1));
238
+ const año = this.dateAdapter.getYear(mesActualValue);
239
+ const mes = this.dateAdapter.getMonth(mesActualValue);
240
+ const mesAnteriorDate = this.dateAdapter.createDate(año, mes - 1, 1);
241
+ this.mesAnterior.set(mesAnteriorDate);
115
242
  this.generarCalendarios();
116
243
  }
117
244
  this.onTouched();
@@ -125,18 +252,18 @@ class DualDatepickerComponent {
125
252
  this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));
126
253
  }
127
254
  generarCalendarioMes(fecha) {
128
- const año = fecha.getFullYear();
129
- const mes = fecha.getMonth();
130
- const primerDia = new Date(año, mes, 1);
131
- const ultimoDia = new Date(año, mes + 1, 0);
132
- const diasEnMes = ultimoDia.getDate();
133
- const primerDiaSemana = primerDia.getDay();
255
+ const año = this.dateAdapter.getYear(fecha);
256
+ const mes = this.dateAdapter.getMonth(fecha);
257
+ const primerDia = this.dateAdapter.createDate(año, mes, 1);
258
+ const ultimoDia = this.dateAdapter.createDate(año, mes + 1, 0);
259
+ const diasEnMes = this.dateAdapter.getDate(ultimoDia);
260
+ const primerDiaSemana = this.dateAdapter.getDay(primerDia);
134
261
  const diasMes = [];
135
262
  for (let i = 0; i < primerDiaSemana; i++) {
136
263
  diasMes.push({ dia: null, esMesActual: false });
137
264
  }
138
265
  for (let dia = 1; dia <= diasEnMes; dia++) {
139
- const fechaDia = new Date(año, mes, dia);
266
+ const fechaDia = this.dateAdapter.createDate(año, mes, dia);
140
267
  const fechaStr = this.formatearFecha(fechaDia);
141
268
  diasMes.push({
142
269
  dia: dia,
@@ -184,22 +311,26 @@ class DualDatepickerComponent {
184
311
  }
185
312
  cambiarMes(direccion) {
186
313
  const mesActualValue = this.mesActual();
187
- this.mesActual.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() + direccion, 1));
188
- const nuevoMesActual = this.mesActual();
189
- this.mesAnterior.set(new Date(nuevoMesActual.getFullYear(), nuevoMesActual.getMonth() - 1, 1));
314
+ const año = this.dateAdapter.getYear(mesActualValue);
315
+ const mes = this.dateAdapter.getMonth(mesActualValue);
316
+ const nuevoMesActual = this.dateAdapter.createDate(año, mes + direccion, 1);
317
+ this.mesActual.set(nuevoMesActual);
318
+ const añoNuevo = this.dateAdapter.getYear(nuevoMesActual);
319
+ const mesNuevo = this.dateAdapter.getMonth(nuevoMesActual);
320
+ const mesAnteriorNuevo = this.dateAdapter.createDate(añoNuevo, mesNuevo - 1, 1);
321
+ this.mesAnterior.set(mesAnteriorNuevo);
190
322
  this.generarCalendarios();
191
323
  }
192
324
  getNombreMes(fecha) {
193
325
  const monthNames = this.locale.monthNames || this.defaultMonthNames;
194
- return `${monthNames[fecha.getMonth()]} ${fecha.getFullYear()}`;
326
+ return `${monthNames[this.dateAdapter.getMonth(fecha)]} ${this.dateAdapter.getYear(fecha)}`;
195
327
  }
196
328
  getDayNames() {
197
329
  return this.locale.dayNamesShort || this.defaultDayNamesShort;
198
330
  }
199
331
  seleccionarRangoPredefinido(preset) {
200
- const hoy = new Date();
201
- const fechaInicio = new Date(hoy);
202
- fechaInicio.setDate(hoy.getDate() - preset.daysAgo);
332
+ const hoy = this.dateAdapter.today();
333
+ const fechaInicio = this.dateAdapter.addDays(hoy, -preset.daysAgo);
203
334
  this.fechaInicio = this.formatearFecha(fechaInicio);
204
335
  this.fechaFin = this.formatearFecha(hoy);
205
336
  this.actualizarRangoFechasTexto();
@@ -270,6 +401,10 @@ class DualDatepickerComponent {
270
401
  provide: NG_VALUE_ACCESSOR,
271
402
  useExisting: forwardRef(() => DualDatepickerComponent),
272
403
  multi: true
404
+ },
405
+ {
406
+ provide: DATE_ADAPTER,
407
+ useClass: NativeDateAdapter
273
408
  }
274
409
  ], usesOnChanges: true, ngImport: i0, template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: ReactiveFormsModule }] });
275
410
  }
@@ -280,6 +415,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
280
415
  provide: NG_VALUE_ACCESSOR,
281
416
  useExisting: forwardRef(() => DualDatepickerComponent),
282
417
  multi: true
418
+ },
419
+ {
420
+ provide: DATE_ADAPTER,
421
+ useClass: NativeDateAdapter
283
422
  }
284
423
  ], template: "<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n \u00D7\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n", styles: [".datepicker-wrapper{position:relative;width:100%}.datepicker-wrapper .datepicker-input{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;cursor:pointer}.datepicker-wrapper .datepicker-input:hover{border-color:var(--input-border-hover, #ced4da)}.datepicker-wrapper .datepicker-input:focus{border-color:var(--input-border-focus, #80bdff);box-shadow:0 0 0 .2rem #007bff40;outline:0}.datepicker-wrapper .datepicker-input::placeholder{color:#6c757d;opacity:1}.datepicker-wrapper .datepicker-input:disabled,.datepicker-wrapper .datepicker-input[readonly]{background-color:#e9ecef;opacity:1}.date-picker-dropdown{position:absolute;top:100%;left:0;margin-top:4px;background:#fff;border:1px solid #e1e4e8;border-radius:8px;box-shadow:0 4px 12px #00000014,0 0 1px #00000014;padding:16px;z-index:1060;min-width:680px}@media (max-width: 768px){.date-picker-dropdown{min-width:100%;left:0;right:0}}.date-picker-header-only-close{display:flex;justify-content:flex-end;margin-bottom:12px}.date-picker-header-only-close .btn-close-calendar{background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;border-radius:6px;cursor:pointer;transition:all .15s ease;font-size:1.5rem;line-height:1}.date-picker-header-only-close .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-header-only-close .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-presets{display:flex;gap:6px;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid #e5e7eb;align-items:center}@media (max-width: 768px){.date-picker-presets{flex-wrap:wrap}}.date-picker-presets button{font-size:.75rem;padding:6px 14px;border:none;background-color:#f9fafb;color:#374151;border-radius:6px;transition:all .15s ease;font-weight:500;cursor:pointer;border:1px solid #e5e7eb}.date-picker-presets button:hover{background-color:#f3f4f6;border-color:#d1d5db;transform:translateY(-1px);box-shadow:0 2px 4px #0000000f}.date-picker-presets button:active{transform:translateY(0);box-shadow:none}.date-picker-presets .btn-close-calendar{margin-left:auto;background-color:transparent;border:1px solid transparent;color:#6b7280;padding:6px 10px;font-size:1.5rem;line-height:1}.date-picker-presets .btn-close-calendar:hover{background-color:#fee;border-color:#fcc;color:#dc2626;transform:translateY(-1px);box-shadow:0 2px 4px #dc26261a}.date-picker-presets .btn-close-calendar:active{transform:translateY(0);box-shadow:none}.date-picker-calendars{display:flex;gap:32px}@media (max-width: 768px){.date-picker-calendars{flex-direction:column;gap:16px}}.date-picker-calendar{flex:1}.date-picker-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;padding:0 4px}.date-picker-header span{font-size:.813rem;font-weight:600;color:#111827}.date-picker-header button{padding:4px;color:#6b7280;text-decoration:none;border-radius:6px;transition:all .15s ease;border:none;background:transparent;cursor:pointer}.date-picker-header button:hover{background-color:#f3f4f6;color:#111827}.date-picker-weekdays{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}.date-picker-weekdays span{text-align:center;font-size:.625rem;font-weight:600;color:#6b7280;padding:6px}.date-picker-days{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}.date-picker-day{aspect-ratio:1;border:none;background:transparent;border-radius:50%;font-size:.75rem;cursor:pointer;transition:all .15s ease;color:#374151;font-weight:400}.date-picker-day:hover:not(:disabled):not(.selected){background-color:#f3f4f6;color:#111827}.date-picker-day.empty{visibility:hidden}.date-picker-day.selected{background-color:#222;color:#fff;font-weight:600}.date-picker-day.in-range{background-color:#f9fafb;border-radius:0}.date-picker-day:disabled{cursor:not-allowed;opacity:.3}.date-picker-footer{padding:12px;border-top:1px solid #e1e4e8;display:flex;justify-content:center;gap:8px}.date-picker-footer .btn-clear{padding:8px 16px;background-color:#f6f8fa;border:1px solid #d0d7de;border-radius:6px;font-size:.875rem;font-weight:500;color:#24292f;cursor:pointer;transition:all .15s ease}.date-picker-footer .btn-clear:hover{background-color:#f3f4f6;border-color:#8c959f;transform:translateY(-1px);box-shadow:0 2px 4px #0000000d}.date-picker-footer .btn-clear:active{transform:translateY(0);box-shadow:none;background-color:#e9ecef}\n"] }]
285
424
  }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { placeholder: [{
@@ -331,5 +470,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
331
470
  * Generated bundle index. Do not edit.
332
471
  */
333
472
 
334
- export { DualDatepickerComponent };
473
+ export { DATE_ADAPTER, DateAdapter, DualDatepickerComponent, NativeDateAdapter };
335
474
  //# sourceMappingURL=oneluiz-dual-datepicker.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"oneluiz-dual-datepicker.mjs","sources":["../../src/dual-datepicker.component.ts","../../src/dual-datepicker.component.html","../../src/public-api.ts","../../src/oneluiz-dual-datepicker.ts"],"sourcesContent":["import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, HostListener, ElementRef, forwardRef, signal, computed, effect } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\n\nexport interface DateRange {\n fechaInicio: string;\n fechaFin: string;\n rangoTexto: string;\n}\n\nexport interface PresetConfig {\n label: string;\n daysAgo: number;\n}\n\nexport interface LocaleConfig {\n monthNames?: string[];\n monthNamesShort?: string[];\n dayNames?: string[];\n dayNamesShort?: string[];\n firstDayOfWeek?: number; // 0 = Sunday, 1 = Monday, etc.\n}\n\n@Component({\n selector: 'ngx-dual-datepicker',\n standalone: true,\n imports: [CommonModule, FormsModule, ReactiveFormsModule],\n templateUrl: './dual-datepicker.component.html',\n styleUrl: './dual-datepicker.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DualDatepickerComponent),\n multi: true\n }\n ]\n})\nexport class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {\n @Input() placeholder: string = 'Select date range';\n @Input() fechaInicio: string = '';\n @Input() fechaFin: string = '';\n @Input() showPresets: boolean = true;\n @Input() showClearButton: boolean = false;\n @Input() closeOnSelection: boolean = true;\n @Input() closeOnPresetSelection: boolean = true;\n @Input() closeOnClickOutside: boolean = true;\n @Input() presets: PresetConfig[] = [\n { label: 'Last month', daysAgo: 30 },\n { label: 'Last 6 months', daysAgo: 180 },\n { label: 'Last year', daysAgo: 365 }\n ];\n @Input() inputBackgroundColor: string = '#fff';\n @Input() inputTextColor: string = '#495057';\n @Input() inputBorderColor: string = '#ced4da';\n @Input() inputBorderColorHover: string = '#ced4da';\n @Input() inputBorderColorFocus: string = '#80bdff';\n @Input() inputPadding: string = '0.375rem 0.75rem';\n @Input() locale: LocaleConfig = {};\n\n @Output() dateRangeChange = new EventEmitter<DateRange>();\n @Output() dateRangeSelected = new EventEmitter<DateRange>();\n\n // Signals for reactive state\n mostrarDatePicker = signal(false);\n rangoFechas = signal('');\n fechaSeleccionandoInicio = signal(true);\n mesActual = signal(new Date());\n mesAnterior = signal(new Date());\n diasMesActual = signal<any[]>([]);\n diasMesAnterior = signal<any[]>([]);\n isDisabled = signal(false);\n\n // Computed values\n nombreMesActual = computed(() => this.getNombreMes(this.mesActual()));\n nombreMesAnterior = computed(() => this.getNombreMes(this.mesAnterior()));\n diasSemana = computed(() => this.getDayNames());\n\n private readonly defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n private readonly defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n private readonly defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n private readonly defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];\n\n // ControlValueAccessor callbacks\n private onChange: (value: DateRange | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n constructor(private elementRef: ElementRef) {\n // Effect to emit changes when dates change\n effect(() => {\n const rango = this.rangoFechas();\n if (this.fechaInicio || this.fechaFin) {\n this.onChange(this.getDateRangeValue());\n }\n });\n }\n\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n if (this.mostrarDatePicker() && this.closeOnClickOutside) {\n const clickedInside = this.elementRef.nativeElement.contains(event.target);\n if (!clickedInside) {\n this.cerrarDatePicker();\n }\n }\n }\n\n ngOnInit(): void {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['fechaInicio'] || changes['fechaFin']) {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n } else if (!this.fechaInicio && !this.fechaFin) {\n this.rangoFechas.set('');\n }\n }\n }\n\n formatearFecha(fecha: Date): string {\n const year = fecha.getFullYear();\n const month = String(fecha.getMonth() + 1).padStart(2, '0');\n const day = String(fecha.getDate()).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n formatearFechaDisplay(fechaStr: string): string {\n if (!fechaStr) return '';\n const fecha = new Date(fechaStr + 'T00:00:00');\n const monthNames = this.locale.monthNamesShort || this.defaultMonthNamesShort;\n return `${fecha.getDate()} ${monthNames[fecha.getMonth()]}`;\n }\n\n actualizarRangoFechasTexto(): void {\n if (this.fechaInicio && this.fechaFin) {\n const inicio = this.formatearFechaDisplay(this.fechaInicio);\n const fin = this.formatearFechaDisplay(this.fechaFin);\n this.rangoFechas.set(`${inicio} - ${fin}`);\n } else {\n this.rangoFechas.set('');\n }\n }\n\n toggleDatePicker(): void {\n this.mostrarDatePicker.update(value => !value);\n if (this.mostrarDatePicker()) {\n this.fechaSeleccionandoInicio.set(true);\n const mesActualValue = this.mesActual();\n this.mesAnterior.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() - 1, 1));\n this.generarCalendarios();\n }\n this.onTouched();\n }\n\n cerrarDatePicker(): void {\n this.mostrarDatePicker.set(false);\n this.onTouched();\n }\n\n generarCalendarios(): void {\n this.diasMesAnterior.set(this.generarCalendarioMes(this.mesAnterior()));\n this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));\n }\n\n generarCalendarioMes(fecha: Date): any[] {\n const año = fecha.getFullYear();\n const mes = fecha.getMonth();\n const primerDia = new Date(año, mes, 1);\n const ultimoDia = new Date(año, mes + 1, 0);\n const diasEnMes = ultimoDia.getDate();\n const primerDiaSemana = primerDia.getDay();\n\n const diasMes = [];\n\n for (let i = 0; i < primerDiaSemana; i++) {\n diasMes.push({ dia: null, esMesActual: false });\n }\n\n for (let dia = 1; dia <= diasEnMes; dia++) {\n const fechaDia = new Date(año, mes, dia);\n const fechaStr = this.formatearFecha(fechaDia);\n diasMes.push({\n dia: dia,\n fecha: fechaStr,\n esMesActual: true,\n esInicio: this.fechaInicio === fechaStr,\n esFin: this.fechaFin === fechaStr,\n enRango: this.estaEnRango(fechaStr)\n });\n }\n\n return diasMes;\n }\n\n estaEnRango(fechaStr: string): boolean {\n if (!this.fechaInicio || !this.fechaFin) return false;\n return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;\n }\n\n seleccionarDia(diaObj: any): void {\n if (!diaObj.esMesActual || this.isDisabled()) return;\n\n if (this.fechaSeleccionandoInicio()) {\n this.fechaInicio = diaObj.fecha;\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.fechaSeleccionandoInicio.set(false);\n this.emitirCambio();\n } else {\n if (diaObj.fecha < this.fechaInicio) {\n this.fechaFin = this.fechaInicio;\n this.fechaInicio = diaObj.fecha;\n } else {\n this.fechaFin = diaObj.fecha;\n }\n this.actualizarRangoFechasTexto();\n if (this.closeOnSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.emitirSeleccion();\n }\n this.generarCalendarios();\n }\n\n cambiarMes(direccion: number): void {\n const mesActualValue = this.mesActual();\n this.mesActual.set(new Date(mesActualValue.getFullYear(), mesActualValue.getMonth() + direccion, 1));\n const nuevoMesActual = this.mesActual();\n this.mesAnterior.set(new Date(nuevoMesActual.getFullYear(), nuevoMesActual.getMonth() - 1, 1));\n this.generarCalendarios();\n }\n\n getNombreMes(fecha: Date): string {\n const monthNames = this.locale.monthNames || this.defaultMonthNames;\n return `${monthNames[fecha.getMonth()]} ${fecha.getFullYear()}`;\n }\n\n getDayNames(): string[] {\n return this.locale.dayNamesShort || this.defaultDayNamesShort;\n }\n\n seleccionarRangoPredefinido(preset: PresetConfig): void {\n const hoy = new Date();\n const fechaInicio = new Date(hoy);\n fechaInicio.setDate(hoy.getDate() - preset.daysAgo);\n\n this.fechaInicio = this.formatearFecha(fechaInicio);\n this.fechaFin = this.formatearFecha(hoy);\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n if (this.closeOnPresetSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.emitirSeleccion();\n }\n\n limpiar(): void {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.mostrarDatePicker.set(false);\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.onTouched();\n }\n\n private emitirCambio(): void {\n this.dateRangeChange.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private emitirSeleccion(): void {\n this.dateRangeSelected.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private getDateRangeValue(): DateRange {\n return {\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n };\n }\n\n // ControlValueAccessor implementation\n writeValue(value: DateRange | null): void {\n if (value) {\n this.fechaInicio = value.fechaInicio || '';\n this.fechaFin = value.fechaFin || '';\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n } else {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n }\n }\n\n registerOnChange(fn: (value: DateRange | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.isDisabled.set(isDisabled);\n }\n}\n","<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n","/**\n * Public API Surface of @oneluiz/dual-datepicker\n */\n\nexport { DualDatepickerComponent } from './dual-datepicker.component';\nexport type { DateRange, PresetConfig, LocaleConfig } from './dual-datepicker.component';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"oneluiz-dual-datepicker.mjs","sources":["../../src/date-adapter.ts","../../src/native-date-adapter.ts","../../src/dual-datepicker.component.ts","../../src/dual-datepicker.component.html","../../src/public-api.ts","../../src/oneluiz-dual-datepicker.ts"],"sourcesContent":["import { InjectionToken } from '@angular/core';\n\n/**\n * Abstract class for date adapters.\n * Allows the component to work with different date libraries (Date, DayJS, date-fns, Luxon, etc.)\n */\nexport abstract class DateAdapter<T = any> {\n /**\n * Parses a value into a date object\n * @param value - Value to parse (string, number, or date object)\n * @returns Parsed date object\n */\n abstract parse(value: any): T | null;\n\n /**\n * Formats a date object into a string\n * @param date - Date object to format\n * @param format - Optional format string\n * @returns Formatted date string\n */\n abstract format(date: T, format?: string): string;\n\n /**\n * Adds days to a date\n * @param date - Date object\n * @param days - Number of days to add (can be negative)\n * @returns New date object\n */\n abstract addDays(date: T, days: number): T;\n\n /**\n * Adds months to a date\n * @param date - Date object\n * @param months - Number of months to add (can be negative)\n * @returns New date object\n */\n abstract addMonths(date: T, months: number): T;\n\n /**\n * Gets the year from a date\n * @param date - Date object\n * @returns Year number\n */\n abstract getYear(date: T): number;\n\n /**\n * Gets the month from a date (0-11)\n * @param date - Date object\n * @returns Month number (0-11)\n */\n abstract getMonth(date: T): number;\n\n /**\n * Gets the day of month from a date\n * @param date - Date object\n * @returns Day of month (1-31)\n */\n abstract getDate(date: T): number;\n\n /**\n * Gets the day of week from a date (0-6, Sunday = 0)\n * @param date - Date object\n * @returns Day of week (0-6)\n */\n abstract getDay(date: T): number;\n\n /**\n * Creates a new date object\n * @param year - Year\n * @param month - Month (0-11)\n * @param date - Day of month (1-31)\n * @returns New date object\n */\n abstract createDate(year: number, month: number, date: number): T;\n\n /**\n * Gets today's date\n * @returns Today's date object\n */\n abstract today(): T;\n\n /**\n * Checks if two dates are the same day\n * @param a - First date\n * @param b - Second date\n * @returns True if same day\n */\n abstract isSameDay(a: T | null, b: T | null): boolean;\n\n /**\n * Checks if a date is before another\n * @param a - First date\n * @param b - Second date\n * @returns True if a is before b\n */\n abstract isBefore(a: T | null, b: T | null): boolean;\n\n /**\n * Checks if a date is after another\n * @param a - First date\n * @param b - Second date\n * @returns True if a is after b\n */\n abstract isAfter(a: T | null, b: T | null): boolean;\n\n /**\n * Checks if a date is between two other dates\n * @param date - Date to check\n * @param start - Start date\n * @param end - End date\n * @returns True if date is between start and end\n */\n abstract isBetween(date: T | null, start: T | null, end: T | null): boolean;\n\n /**\n * Clones a date object\n * @param date - Date to clone\n * @returns Cloned date object\n */\n abstract clone(date: T): T;\n\n /**\n * Checks if a value is a valid date\n * @param date - Value to check\n * @returns True if valid date\n */\n abstract isValid(date: any): boolean;\n}\n\n/**\n * Injection token for DateAdapter\n */\nexport const DATE_ADAPTER = new InjectionToken<DateAdapter>('DATE_ADAPTER');\n","import { Injectable } from '@angular/core';\nimport { DateAdapter } from './date-adapter';\n\n/**\n * Date adapter implementation for native JavaScript Date objects\n * This is the default adapter used by the component\n */\n@Injectable()\nexport class NativeDateAdapter extends DateAdapter<Date> {\n parse(value: any): Date | null {\n if (!value) return null;\n \n if (value instanceof Date) {\n return new Date(value);\n }\n \n if (typeof value === 'string' || typeof value === 'number') {\n const date = new Date(value);\n return this.isValid(date) ? date : null;\n }\n \n return null;\n }\n\n format(date: Date, format: string = 'YYYY-MM-DD'): string {\n if (!this.isValid(date)) return '';\n \n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n \n // Simple format implementation\n switch (format) {\n case 'YYYY-MM-DD':\n return `${year}-${month}-${day}`;\n case 'MM/DD/YYYY':\n return `${month}/${day}/${year}`;\n case 'DD/MM/YYYY':\n return `${day}/${month}/${year}`;\n default:\n return `${year}-${month}-${day}`;\n }\n }\n\n addDays(date: Date, days: number): Date {\n const result = this.clone(date);\n result.setDate(result.getDate() + days);\n return result;\n }\n\n addMonths(date: Date, months: number): Date {\n const result = this.clone(date);\n result.setMonth(result.getMonth() + months);\n return result;\n }\n\n getYear(date: Date): number {\n return date.getFullYear();\n }\n\n getMonth(date: Date): number {\n return date.getMonth();\n }\n\n getDate(date: Date): number {\n return date.getDate();\n }\n\n getDay(date: Date): number {\n return date.getDay();\n }\n\n createDate(year: number, month: number, date: number): Date {\n return new Date(year, month, date);\n }\n\n today(): Date {\n return new Date();\n }\n\n isSameDay(a: Date | null, b: Date | null): boolean {\n if (!a || !b) return false;\n if (!this.isValid(a) || !this.isValid(b)) return false;\n \n return (\n a.getFullYear() === b.getFullYear() &&\n a.getMonth() === b.getMonth() &&\n a.getDate() === b.getDate()\n );\n }\n\n isBefore(a: Date | null, b: Date | null): boolean {\n if (!a || !b) return false;\n if (!this.isValid(a) || !this.isValid(b)) return false;\n \n return a.getTime() < b.getTime();\n }\n\n isAfter(a: Date | null, b: Date | null): boolean {\n if (!a || !b) return false;\n if (!this.isValid(a) || !this.isValid(b)) return false;\n \n return a.getTime() > b.getTime();\n }\n\n isBetween(date: Date | null, start: Date | null, end: Date | null): boolean {\n if (!date || !start || !end) return false;\n if (!this.isValid(date) || !this.isValid(start) || !this.isValid(end)) return false;\n \n const dateTime = date.getTime();\n const startTime = start.getTime();\n const endTime = end.getTime();\n \n return dateTime >= startTime && dateTime <= endTime;\n }\n\n clone(date: Date): Date {\n return new Date(date.getTime());\n }\n\n isValid(date: any): boolean {\n return date instanceof Date && !isNaN(date.getTime());\n }\n}\n","import { Component, Input, Output, EventEmitter, OnInit, OnChanges, SimpleChanges, HostListener, ElementRef, forwardRef, signal, computed, effect, inject } from '@angular/core';\nimport { CommonModule } from '@angular/common';\nimport { FormsModule, ReactiveFormsModule, ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { DateAdapter, DATE_ADAPTER } from './date-adapter';\nimport { NativeDateAdapter } from './native-date-adapter';\n\nexport interface DateRange {\n fechaInicio: string;\n fechaFin: string;\n rangoTexto: string;\n}\n\nexport interface PresetConfig {\n label: string;\n daysAgo: number;\n}\n\nexport interface LocaleConfig {\n monthNames?: string[];\n monthNamesShort?: string[];\n dayNames?: string[];\n dayNamesShort?: string[];\n firstDayOfWeek?: number; // 0 = Sunday, 1 = Monday, etc.\n}\n\n@Component({\n selector: 'ngx-dual-datepicker',\n standalone: true,\n imports: [CommonModule, FormsModule, ReactiveFormsModule],\n templateUrl: './dual-datepicker.component.html',\n styleUrl: './dual-datepicker.component.scss',\n providers: [\n {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => DualDatepickerComponent),\n multi: true\n },\n {\n provide: DATE_ADAPTER,\n useClass: NativeDateAdapter\n }\n ]\n})\nexport class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {\n @Input() placeholder: string = 'Select date range';\n @Input() fechaInicio: string = '';\n @Input() fechaFin: string = '';\n @Input() showPresets: boolean = true;\n @Input() showClearButton: boolean = false;\n @Input() closeOnSelection: boolean = true;\n @Input() closeOnPresetSelection: boolean = true;\n @Input() closeOnClickOutside: boolean = true;\n @Input() presets: PresetConfig[] = [\n { label: 'Last month', daysAgo: 30 },\n { label: 'Last 6 months', daysAgo: 180 },\n { label: 'Last year', daysAgo: 365 }\n ];\n @Input() inputBackgroundColor: string = '#fff';\n @Input() inputTextColor: string = '#495057';\n @Input() inputBorderColor: string = '#ced4da';\n @Input() inputBorderColorHover: string = '#ced4da';\n @Input() inputBorderColorFocus: string = '#80bdff';\n @Input() inputPadding: string = '0.375rem 0.75rem';\n @Input() locale: LocaleConfig = {};\n\n @Output() dateRangeChange = new EventEmitter<DateRange>();\n @Output() dateRangeSelected = new EventEmitter<DateRange>();\n\n // Date adapter injection\n private dateAdapter = inject<DateAdapter>(DATE_ADAPTER);\n\n // Signals for reactive state\n mostrarDatePicker = signal(false);\n rangoFechas = signal('');\n fechaSeleccionandoInicio = signal(true);\n mesActual = signal(this.dateAdapter.today());\n mesAnterior = signal(this.dateAdapter.today());\n diasMesActual = signal<any[]>([]);\n diasMesAnterior = signal<any[]>([]);\n isDisabled = signal(false);\n\n // Computed values\n nombreMesActual = computed(() => this.getNombreMes(this.mesActual()));\n nombreMesAnterior = computed(() => this.getNombreMes(this.mesAnterior()));\n diasSemana = computed(() => this.getDayNames());\n\n private readonly defaultMonthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\n private readonly defaultMonthNamesShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\n private readonly defaultDayNames = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];\n private readonly defaultDayNamesShort = ['S', 'M', 'T', 'W', 'T', 'F', 'S'];\n\n // ControlValueAccessor callbacks\n private onChange: (value: DateRange | null) => void = () => {};\n private onTouched: () => void = () => {};\n\n constructor(private elementRef: ElementRef) {\n // Effect to emit changes when dates change\n effect(() => {\n const rango = this.rangoFechas();\n if (this.fechaInicio || this.fechaFin) {\n this.onChange(this.getDateRangeValue());\n }\n });\n }\n\n @HostListener('document:click', ['$event'])\n onClickOutside(event: MouseEvent): void {\n if (this.mostrarDatePicker() && this.closeOnClickOutside) {\n const clickedInside = this.elementRef.nativeElement.contains(event.target);\n if (!clickedInside) {\n this.cerrarDatePicker();\n }\n }\n }\n\n ngOnInit(): void {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n if (changes['fechaInicio'] || changes['fechaFin']) {\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n } else if (!this.fechaInicio && !this.fechaFin) {\n this.rangoFechas.set('');\n }\n }\n }\n\n formatearFecha(fecha: Date): string {\n const year = this.dateAdapter.getYear(fecha);\n const month = String(this.dateAdapter.getMonth(fecha) + 1).padStart(2, '0');\n const day = String(this.dateAdapter.getDate(fecha)).padStart(2, '0');\n return `${year}-${month}-${day}`;\n }\n\n formatearFechaDisplay(fechaStr: string): string {\n if (!fechaStr) return '';\n const fecha = this.dateAdapter.parse(fechaStr);\n if (!fecha) return '';\n const monthNames = this.locale.monthNamesShort || this.defaultMonthNamesShort;\n return `${this.dateAdapter.getDate(fecha)} ${monthNames[this.dateAdapter.getMonth(fecha)]}`;\n }\n\n actualizarRangoFechasTexto(): void {\n if (this.fechaInicio && this.fechaFin) {\n const inicio = this.formatearFechaDisplay(this.fechaInicio);\n const fin = this.formatearFechaDisplay(this.fechaFin);\n this.rangoFechas.set(`${inicio} - ${fin}`);\n } else {\n this.rangoFechas.set('');\n }\n }\n\n toggleDatePicker(): void {\n this.mostrarDatePicker.update(value => !value);\n if (this.mostrarDatePicker()) {\n this.fechaSeleccionandoInicio.set(true);\n const mesActualValue = this.mesActual();\n const año = this.dateAdapter.getYear(mesActualValue);\n const mes = this.dateAdapter.getMonth(mesActualValue);\n const mesAnteriorDate = this.dateAdapter.createDate(año, mes - 1, 1);\n this.mesAnterior.set(mesAnteriorDate);\n this.generarCalendarios();\n }\n this.onTouched();\n }\n\n cerrarDatePicker(): void {\n this.mostrarDatePicker.set(false);\n this.onTouched();\n }\n\n generarCalendarios(): void {\n this.diasMesAnterior.set(this.generarCalendarioMes(this.mesAnterior()));\n this.diasMesActual.set(this.generarCalendarioMes(this.mesActual()));\n }\n\n generarCalendarioMes(fecha: Date): any[] {\n const año = this.dateAdapter.getYear(fecha);\n const mes = this.dateAdapter.getMonth(fecha);\n const primerDia = this.dateAdapter.createDate(año, mes, 1);\n const ultimoDia = this.dateAdapter.createDate(año, mes + 1, 0);\n const diasEnMes = this.dateAdapter.getDate(ultimoDia);\n const primerDiaSemana = this.dateAdapter.getDay(primerDia);\n\n const diasMes = [];\n\n for (let i = 0; i < primerDiaSemana; i++) {\n diasMes.push({ dia: null, esMesActual: false });\n }\n\n for (let dia = 1; dia <= diasEnMes; dia++) {\n const fechaDia = this.dateAdapter.createDate(año, mes, dia);\n const fechaStr = this.formatearFecha(fechaDia);\n diasMes.push({\n dia: dia,\n fecha: fechaStr,\n esMesActual: true,\n esInicio: this.fechaInicio === fechaStr,\n esFin: this.fechaFin === fechaStr,\n enRango: this.estaEnRango(fechaStr)\n });\n }\n\n return diasMes;\n }\n\n estaEnRango(fechaStr: string): boolean {\n if (!this.fechaInicio || !this.fechaFin) return false;\n return fechaStr >= this.fechaInicio && fechaStr <= this.fechaFin;\n }\n\n seleccionarDia(diaObj: any): void {\n if (!diaObj.esMesActual || this.isDisabled()) return;\n\n if (this.fechaSeleccionandoInicio()) {\n this.fechaInicio = diaObj.fecha;\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.fechaSeleccionandoInicio.set(false);\n this.emitirCambio();\n } else {\n if (diaObj.fecha < this.fechaInicio) {\n this.fechaFin = this.fechaInicio;\n this.fechaInicio = diaObj.fecha;\n } else {\n this.fechaFin = diaObj.fecha;\n }\n this.actualizarRangoFechasTexto();\n if (this.closeOnSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.emitirSeleccion();\n }\n this.generarCalendarios();\n }\n\n cambiarMes(direccion: number): void {\n const mesActualValue = this.mesActual();\n const año = this.dateAdapter.getYear(mesActualValue);\n const mes = this.dateAdapter.getMonth(mesActualValue);\n const nuevoMesActual = this.dateAdapter.createDate(año, mes + direccion, 1);\n this.mesActual.set(nuevoMesActual);\n \n const añoNuevo = this.dateAdapter.getYear(nuevoMesActual);\n const mesNuevo = this.dateAdapter.getMonth(nuevoMesActual);\n const mesAnteriorNuevo = this.dateAdapter.createDate(añoNuevo, mesNuevo - 1, 1);\n this.mesAnterior.set(mesAnteriorNuevo);\n this.generarCalendarios();\n }\n\n getNombreMes(fecha: Date): string {\n const monthNames = this.locale.monthNames || this.defaultMonthNames;\n return `${monthNames[this.dateAdapter.getMonth(fecha)]} ${this.dateAdapter.getYear(fecha)}`;\n }\n\n getDayNames(): string[] {\n return this.locale.dayNamesShort || this.defaultDayNamesShort;\n }\n\n seleccionarRangoPredefinido(preset: PresetConfig): void {\n const hoy = this.dateAdapter.today();\n const fechaInicio = this.dateAdapter.addDays(hoy, -preset.daysAgo);\n\n this.fechaInicio = this.formatearFecha(fechaInicio);\n this.fechaFin = this.formatearFecha(hoy);\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n if (this.closeOnPresetSelection) {\n this.mostrarDatePicker.set(false);\n }\n this.emitirSeleccion();\n }\n\n limpiar(): void {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n this.mostrarDatePicker.set(false);\n this.fechaSeleccionandoInicio.set(true);\n this.emitirCambio();\n this.onTouched();\n }\n\n private emitirCambio(): void {\n this.dateRangeChange.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private emitirSeleccion(): void {\n this.dateRangeSelected.emit({\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n });\n }\n\n private getDateRangeValue(): DateRange {\n return {\n fechaInicio: this.fechaInicio,\n fechaFin: this.fechaFin,\n rangoTexto: this.rangoFechas()\n };\n }\n\n // ControlValueAccessor implementation\n writeValue(value: DateRange | null): void {\n if (value) {\n this.fechaInicio = value.fechaInicio || '';\n this.fechaFin = value.fechaFin || '';\n if (this.fechaInicio && this.fechaFin) {\n this.actualizarRangoFechasTexto();\n this.generarCalendarios();\n }\n } else {\n this.fechaInicio = '';\n this.fechaFin = '';\n this.rangoFechas.set('');\n }\n }\n\n registerOnChange(fn: (value: DateRange | null) => void): void {\n this.onChange = fn;\n }\n\n registerOnTouched(fn: () => void): void {\n this.onTouched = fn;\n }\n\n setDisabledState(isDisabled: boolean): void {\n this.isDisabled.set(isDisabled);\n }\n}\n","<div class=\"datepicker-wrapper\" \n [style.--input-border-hover]=\"inputBorderColorHover\"\n [style.--input-border-focus]=\"inputBorderColorFocus\">\n <input \n type=\"text\" \n class=\"datepicker-input\" \n [value]=\"rangoFechas()\" \n (click)=\"toggleDatePicker()\" \n [placeholder]=\"placeholder\"\n [disabled]=\"isDisabled()\"\n [ngStyle]=\"{\n 'background-color': inputBackgroundColor,\n 'color': inputTextColor,\n 'border-color': inputBorderColor,\n 'padding': inputPadding\n }\"\n readonly>\n\n @if (mostrarDatePicker()) {\n <div class=\"date-picker-dropdown\">\n @if (showPresets) {\n <div class=\"date-picker-presets\">\n @for (preset of presets; track preset.label) {\n <button type=\"button\" (click)=\"seleccionarRangoPredefinido(preset)\">{{ preset.label }}</button>\n }\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n @if (!showPresets) {\n <div class=\"date-picker-header-only-close\">\n <button type=\"button\" class=\"btn-close-calendar\" (click)=\"cerrarDatePicker()\" title=\"Close\">\n ×\n </button>\n </div>\n }\n\n <!-- Calendars -->\n <div class=\"date-picker-calendars\">\n <!-- Previous month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" (click)=\"cambiarMes(-1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesAnterior() }}</span>\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesAnterior(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n\n <!-- Current month calendar -->\n <div class=\"date-picker-calendar\">\n <div class=\"date-picker-header\">\n <button type=\"button\" style=\"visibility: hidden;\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M11.354 1.646a.5.5 0 0 1 0 .708L5.707 8l5.647 5.646a.5.5 0 0 1-.708.708l-6-6a.5.5 0 0 1 0-.708l6-6a.5.5 0 0 1 .708 0z\"/>\n </svg>\n </button>\n <span>{{ nombreMesActual() }}</span>\n <button type=\"button\" (click)=\"cambiarMes(1)\">\n <svg width=\"16\" height=\"16\" fill=\"currentColor\" viewBox=\"0 0 16 16\">\n <path fill-rule=\"evenodd\" d=\"M4.646 1.646a.5.5 0 0 1 .708 0l6 6a.5.5 0 0 1 0 .708l-6 6a.5.5 0 0 1-.708-.708L10.293 8 4.646 2.354a.5.5 0 0 1 0-.708z\"/>\n </svg>\n </button>\n </div>\n <div class=\"date-picker-weekdays\">\n @for (dayName of diasSemana(); track $index) {\n <span>{{ dayName }}</span>\n }\n </div>\n <div class=\"date-picker-days\">\n @for (diaObj of diasMesActual(); track diaObj.fecha || $index) {\n <button \n type=\"button\"\n class=\"date-picker-day\" \n [class.empty]=\"!diaObj.esMesActual\"\n [class.selected]=\"diaObj.esInicio || diaObj.esFin\"\n [class.in-range]=\"diaObj.enRango && !diaObj.esInicio && !diaObj.esFin\"\n (click)=\"seleccionarDia(diaObj)\"\n [disabled]=\"!diaObj.esMesActual\">\n {{ diaObj.dia }}\n </button>\n }\n </div>\n </div>\n </div>\n\n <!-- Footer with clear button -->\n @if (showClearButton) {\n <div class=\"date-picker-footer\">\n <button type=\"button\" class=\"btn-clear\" (click)=\"limpiar()\" title=\"Clear selection\">\n Clear\n </button>\n </div>\n }\n </div>\n }\n</div>\n","/**\n * Public API Surface of @oneluiz/dual-datepicker\n */\n\nexport { DualDatepickerComponent } from './dual-datepicker.component';\nexport type { DateRange, PresetConfig, LocaleConfig } from './dual-datepicker.component';\n\n// Date Adapter System\nexport { DateAdapter, DATE_ADAPTER } from './date-adapter';\nexport { NativeDateAdapter } from './native-date-adapter';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { DateAdapter } from './date-adapter';
2
+ import * as i0 from "@angular/core";
3
+ /**
4
+ * Date adapter implementation for native JavaScript Date objects
5
+ * This is the default adapter used by the component
6
+ */
7
+ export declare class NativeDateAdapter extends DateAdapter<Date> {
8
+ parse(value: any): Date | null;
9
+ format(date: Date, format?: string): string;
10
+ addDays(date: Date, days: number): Date;
11
+ addMonths(date: Date, months: number): Date;
12
+ getYear(date: Date): number;
13
+ getMonth(date: Date): number;
14
+ getDate(date: Date): number;
15
+ getDay(date: Date): number;
16
+ createDate(year: number, month: number, date: number): Date;
17
+ today(): Date;
18
+ isSameDay(a: Date | null, b: Date | null): boolean;
19
+ isBefore(a: Date | null, b: Date | null): boolean;
20
+ isAfter(a: Date | null, b: Date | null): boolean;
21
+ isBetween(date: Date | null, start: Date | null, end: Date | null): boolean;
22
+ clone(date: Date): Date;
23
+ isValid(date: any): boolean;
24
+ static ɵfac: i0.ɵɵFactoryDeclaration<NativeDateAdapter, never>;
25
+ static ɵprov: i0.ɵɵInjectableDeclaration<NativeDateAdapter>;
26
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oneluiz/dual-datepicker",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "A customizable dual-calendar date range picker component for Angular 17+ with Reactive Forms and Signals support",
5
5
  "keywords": [
6
6
  "angular",
package/public-api.d.ts CHANGED
@@ -3,3 +3,5 @@
3
3
  */
4
4
  export { DualDatepickerComponent } from './dual-datepicker.component';
5
5
  export type { DateRange, PresetConfig, LocaleConfig } from './dual-datepicker.component';
6
+ export { DateAdapter, DATE_ADAPTER } from './date-adapter';
7
+ export { NativeDateAdapter } from './native-date-adapter';