ngx-datex 1.0.0 → 1.0.1

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.
@@ -172,11 +172,30 @@ function isSameMonth(date1, date2) {
172
172
  function isSameYear(date1, date2) {
173
173
  return sameYear(date1, date2);
174
174
  }
175
- function formatDateValue(date, formatStr) {
175
+ /**
176
+ * Formats a date using the specified format string and locale.
177
+ * Follows vanilla-daterangepicker logic by always using locale.format.
178
+ *
179
+ * @param date - The date to format
180
+ * @param formatStr - Format string (e.g., 'DD/MM/YYYY', 'MM/DD/YYYY HH:mm')
181
+ * @param locale - Optional locale string (e.g., 'es-ES', 'en-US')
182
+ * @returns Formatted date string
183
+ *
184
+ * @example
185
+ * ```typescript
186
+ * const date = new Date('2024-01-15 14:30:00');
187
+ * formatDateValue(date, 'DD/MM/YYYY'); // '15/01/2024'
188
+ * formatDateValue(date, 'MM/DD/YYYY hh:mm A'); // '01/15/2024 02:30 PM'
189
+ * formatDateValue(date, 'DD/MM/YYYY HH:mm', 'es-ES'); // '15/01/2024 14:30'
190
+ * ```
191
+ */
192
+ function formatDateValue(date, formatStr, locale) {
176
193
  try {
177
- return format(date, formatStr);
194
+ // Use @formkit/tempo with locale support (following vanilla-daterangepicker pattern)
195
+ return format(date, formatStr, locale);
178
196
  }
179
197
  catch {
198
+ // Fallback to manual formatting if tempo fails
180
199
  const year = date.getFullYear();
181
200
  const month = String(date.getMonth() + 1).padStart(2, '0');
182
201
  const day = String(date.getDate()).padStart(2, '0');
@@ -196,9 +215,26 @@ function formatDateValue(date, formatStr) {
196
215
  .replace(/A/g, ampm);
197
216
  }
198
217
  }
199
- function parseDateValue(dateStr, formatStr) {
218
+ /**
219
+ * Parses a date string using the specified format string and locale.
220
+ * Follows vanilla-daterangepicker logic by always using locale.format.
221
+ *
222
+ * @param dateStr - The date string to parse
223
+ * @param formatStr - Format string (e.g., 'DD/MM/YYYY', 'MM/DD/YYYY HH:mm')
224
+ * @param locale - Optional locale string (e.g., 'es-ES', 'en-US')
225
+ * @returns Parsed Date object
226
+ *
227
+ * @example
228
+ * ```typescript
229
+ * const date1 = parseDateValue('15/01/2024', 'DD/MM/YYYY'); // January 15, 2024
230
+ * const date2 = parseDateValue('01/15/2024 02:30 PM', 'MM/DD/YYYY hh:mm A'); // January 15, 2024 14:30
231
+ * const date3 = parseDateValue('15/01/2024 14:30', 'DD/MM/YYYY HH:mm', 'es-ES'); // January 15, 2024 14:30
232
+ * ```
233
+ */
234
+ function parseDateValue(dateStr, formatStr, locale) {
200
235
  try {
201
- const parsed = parse(dateStr, formatStr);
236
+ // Use @formkit/tempo with locale support (following vanilla-daterangepicker pattern)
237
+ const parsed = parse(dateStr, formatStr, locale);
202
238
  if (isValidDate(parsed)) {
203
239
  return parsed;
204
240
  }
@@ -206,6 +242,7 @@ function parseDateValue(dateStr, formatStr) {
206
242
  catch {
207
243
  // Fallback to manual parsing
208
244
  }
245
+ // Manual parsing fallback for common formats
209
246
  if (formatStr === 'YYYY-MM-DD') {
210
247
  const parts = dateStr.split('-');
211
248
  if (parts.length === 3) {
@@ -243,6 +280,7 @@ function parseDateValue(dateStr, formatStr) {
243
280
  return date;
244
281
  }
245
282
  }
283
+ // Final fallback to native Date parsing
246
284
  return new Date(dateStr);
247
285
  }
248
286
  function isSameDate(date1, date2, unit = 'day') {
@@ -255,6 +293,15 @@ function isSameDate(date1, date2, unit = 'day') {
255
293
  return isSameMonth(date1, date2);
256
294
  case 'year':
257
295
  return isSameYear(date1, date2);
296
+ case 'minute':
297
+ return (isSameDay(date1, date2) &&
298
+ date1.getHours() === date2.getHours() &&
299
+ date1.getMinutes() === date2.getMinutes());
300
+ case 'second':
301
+ return (isSameDay(date1, date2) &&
302
+ date1.getHours() === date2.getHours() &&
303
+ date1.getMinutes() === date2.getMinutes() &&
304
+ date1.getSeconds() === date2.getSeconds());
258
305
  default:
259
306
  return false;
260
307
  }
@@ -293,6 +340,7 @@ function isMobileDevice() {
293
340
  * ```
294
341
  */
295
342
  const SPANISH_LOCALE = {
343
+ locale: 'es-ES',
296
344
  direction: 'ltr',
297
345
  format: 'DD/MM/YYYY',
298
346
  separator: ' - ',
@@ -317,6 +365,136 @@ const SPANISH_LOCALE = {
317
365
  ],
318
366
  firstDay: 1, // Lunes como primer día
319
367
  };
368
+ /**
369
+ * Spanish locale with time picker support (24-hour format).
370
+ *
371
+ * Same as SPANISH_LOCALE but with DD/MM/YYYY HH:mm format for time picker usage.
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * <ngx-datex [locale]="SPANISH_LOCALE_WITH_TIME" [timePicker]="true"></ngx-datex>
376
+ * ```
377
+ */
378
+ const SPANISH_LOCALE_WITH_TIME = {
379
+ ...SPANISH_LOCALE,
380
+ format: 'DD/MM/YYYY HH:mm',
381
+ };
382
+ /**
383
+ * Spanish locale with time picker support (12-hour format).
384
+ *
385
+ * Same as SPANISH_LOCALE but with DD/MM/YYYY hh:mm A format for 12-hour time picker.
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * <ngx-datex [locale]="SPANISH_LOCALE_WITH_TIME_12H" [timePicker]="true" [timePicker24Hour]="false"></ngx-datex>
390
+ * ```
391
+ */
392
+ const SPANISH_LOCALE_WITH_TIME_12H = {
393
+ ...SPANISH_LOCALE,
394
+ format: 'DD/MM/YYYY hh:mm A',
395
+ };
396
+ /**
397
+ * US English locale configuration.
398
+ *
399
+ * Provides English language support with MM/DD/YYYY format,
400
+ * English day/month names, and Sunday as the first day of the week.
401
+ *
402
+ * @example
403
+ * ```typescript
404
+ * <ngx-datex [locale]="US_ENGLISH_LOCALE"></ngx-datex>
405
+ * ```
406
+ */
407
+ const US_ENGLISH_LOCALE = {
408
+ locale: 'en-US',
409
+ direction: 'ltr',
410
+ format: 'MM/DD/YYYY',
411
+ separator: ' - ',
412
+ applyLabel: 'Apply',
413
+ cancelLabel: 'Cancel',
414
+ weekLabel: 'W',
415
+ customRangeLabel: 'Custom Range',
416
+ daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
417
+ monthNames: [
418
+ 'January',
419
+ 'February',
420
+ 'March',
421
+ 'April',
422
+ 'May',
423
+ 'June',
424
+ 'July',
425
+ 'August',
426
+ 'September',
427
+ 'October',
428
+ 'November',
429
+ 'December',
430
+ ],
431
+ firstDay: 0, // Sunday as first day
432
+ };
433
+ /**
434
+ * US English locale with time picker support (12-hour format).
435
+ *
436
+ * Same as US_ENGLISH_LOCALE but with MM/DD/YYYY hh:mm A format for time picker usage.
437
+ *
438
+ * @example
439
+ * ```typescript
440
+ * <ngx-datex [locale]="US_ENGLISH_LOCALE_WITH_TIME" [timePicker]="true" [timePicker24Hour]="false"></ngx-datex>
441
+ * ```
442
+ */
443
+ const US_ENGLISH_LOCALE_WITH_TIME = {
444
+ ...US_ENGLISH_LOCALE,
445
+ format: 'MM/DD/YYYY hh:mm A',
446
+ };
447
+ /**
448
+ * ISO format locale configuration.
449
+ *
450
+ * Provides YYYY-MM-DD format commonly used in APIs and databases,
451
+ * with English labels and Monday as the first day of the week.
452
+ *
453
+ * @example
454
+ * ```typescript
455
+ * <ngx-datex [locale]="ISO_LOCALE"></ngx-datex>
456
+ * ```
457
+ */
458
+ const ISO_LOCALE = {
459
+ locale: 'en-US',
460
+ direction: 'ltr',
461
+ format: 'YYYY-MM-DD',
462
+ separator: ' / ',
463
+ applyLabel: 'Apply',
464
+ cancelLabel: 'Cancel',
465
+ weekLabel: 'W',
466
+ customRangeLabel: 'Custom Range',
467
+ daysOfWeek: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
468
+ monthNames: [
469
+ 'January',
470
+ 'February',
471
+ 'March',
472
+ 'April',
473
+ 'May',
474
+ 'June',
475
+ 'July',
476
+ 'August',
477
+ 'September',
478
+ 'October',
479
+ 'November',
480
+ 'December',
481
+ ],
482
+ firstDay: 1, // Monday as first day
483
+ };
484
+ /**
485
+ * ISO format locale with time picker support (24-hour format).
486
+ *
487
+ * Same as ISO_LOCALE but with YYYY-MM-DD HH:mm format for time picker usage.
488
+ *
489
+ * @example
490
+ * ```typescript
491
+ * <ngx-datex [locale]="ISO_LOCALE_WITH_TIME" [timePicker]="true"></ngx-datex>
492
+ * ```
493
+ */
494
+ const ISO_LOCALE_WITH_TIME = {
495
+ ...ISO_LOCALE,
496
+ format: 'YYYY-MM-DD HH:mm',
497
+ };
320
498
  /**
321
499
  * Default Material Design light theme.
322
500
  *
@@ -486,8 +664,8 @@ const DEFAULT_RANGES = {
486
664
  *
487
665
  * // Update configuration
488
666
  * this.datexService.updateConfig({
489
- * dateFormat: 'DD/MM/YYYY',
490
- * firstDayOfWeek: 1
667
+ * firstDayOfWeek: 1,
668
+ * businessDaysOnly: true
491
669
  * });
492
670
  *
493
671
  * // Format a date range
@@ -505,9 +683,9 @@ class NgxDatexService {
505
683
  * @example
506
684
  * ```typescript
507
685
  * this.datexService.updateConfig({
508
- * dateFormat: 'YYYY-MM-DD',
509
686
  * firstDayOfWeek: 0, // Sunday
510
- * businessDaysOnly: true
687
+ * businessDaysOnly: true,
688
+ * showWeekNumbers: true
511
689
  * });
512
690
  * ```
513
691
  */
@@ -1302,11 +1480,20 @@ class NgxDatexCalendarService {
1302
1480
  onLeftMonthChange(maxLeftMonth);
1303
1481
  }
1304
1482
  }
1305
- setStartDate(startDate, minDate, maxDate, timePicker, timePickerIncrement) {
1483
+ setStartDate(startDate, minDate, maxDate, timePicker, timePickerIncrement, currentStartDate) {
1306
1484
  let newStartDate = new Date(startDate);
1307
1485
  if (!timePicker) {
1308
1486
  newStartDate = startOfDay(newStartDate);
1309
1487
  }
1488
+ else if (currentStartDate && timePicker) {
1489
+ // When timePicker is enabled, preserve existing time if only date is changing
1490
+ if (newStartDate.getFullYear() !== currentStartDate.getFullYear() ||
1491
+ newStartDate.getMonth() !== currentStartDate.getMonth() ||
1492
+ newStartDate.getDate() !== currentStartDate.getDate()) {
1493
+ // Only date changed, preserve time
1494
+ newStartDate.setHours(currentStartDate.getHours(), currentStartDate.getMinutes(), currentStartDate.getSeconds(), currentStartDate.getMilliseconds());
1495
+ }
1496
+ }
1310
1497
  if (timePicker && timePickerIncrement) {
1311
1498
  const minutes = newStartDate.getMinutes();
1312
1499
  const roundedMinutes = Math.round(minutes / timePickerIncrement) * timePickerIncrement;
@@ -1330,11 +1517,20 @@ class NgxDatexCalendarService {
1330
1517
  }
1331
1518
  return newStartDate;
1332
1519
  }
1333
- setEndDate(endDate, startDate, maxDate, maxSpan, timePicker, timePickerIncrement) {
1520
+ setEndDate(endDate, startDate, maxDate, maxSpan, timePicker, timePickerIncrement, currentEndDate) {
1334
1521
  let newEndDate = new Date(endDate);
1335
1522
  if (!timePicker) {
1336
1523
  newEndDate = endOfDay(newEndDate);
1337
1524
  }
1525
+ else if (currentEndDate && timePicker) {
1526
+ // When timePicker is enabled, preserve existing time if only date is changing
1527
+ if (newEndDate.getFullYear() !== currentEndDate.getFullYear() ||
1528
+ newEndDate.getMonth() !== currentEndDate.getMonth() ||
1529
+ newEndDate.getDate() !== currentEndDate.getDate()) {
1530
+ // Only date changed, preserve time
1531
+ newEndDate.setHours(currentEndDate.getHours(), currentEndDate.getMinutes(), currentEndDate.getSeconds(), currentEndDate.getMilliseconds());
1532
+ }
1533
+ }
1338
1534
  if (timePicker && timePickerIncrement) {
1339
1535
  const minutes = newEndDate.getMinutes();
1340
1536
  const roundedMinutes = Math.round(minutes / timePickerIncrement) * timePickerIncrement;
@@ -1533,28 +1729,165 @@ class NgxDatex {
1533
1729
  * @example
1534
1730
  * ```typescript
1535
1731
  * const config: NgxDatexConfig = {
1536
- * dateFormat: 'DD/MM/YYYY',
1537
1732
  * firstDayOfWeek: 1,
1538
- * businessDaysOnly: true
1733
+ * businessDaysOnly: true,
1734
+ * showWeekNumbers: true
1539
1735
  * };
1540
1736
  * ```
1541
1737
  */
1542
1738
  config = input({}, ...(ngDevMode ? [{ debugName: "config" }] : []));
1543
1739
  /**
1544
1740
  * Localization settings for internationalization.
1545
- * Controls language, date formats, and UI text.
1741
+ * Controls language, date formats, UI text, and regional preferences.
1742
+ *
1743
+ * This is the primary configuration for adapting the date picker to different
1744
+ * languages, regions, and cultural conventions. The most important property
1745
+ * is `format`, which controls how dates are displayed and parsed.
1546
1746
  *
1547
1747
  * @default SPANISH_LOCALE
1548
1748
  *
1549
- * @example
1749
+ * ## Key Properties:
1750
+ *
1751
+ * - **`format`**: Date format string (REQUIRED for timePicker usage)
1752
+ * - **`locale`**: Locale code for @formkit/tempo formatting
1753
+ * - **`separator`**: Text between start and end dates
1754
+ * - **`daysOfWeek`**: Short day names array
1755
+ * - **`monthNames`**: Full month names array
1756
+ * - **`applyLabel`**: Apply button text
1757
+ * - **`cancelLabel`**: Cancel button text
1758
+ *
1759
+ * ## Format Examples:
1760
+ *
1761
+ * ### Date Only Formats:
1762
+ * ```typescript
1763
+ * // European format (DD/MM/YYYY)
1764
+ * const europeanLocale: NgxDatexLocale = {
1765
+ * locale: 'es-ES',
1766
+ * format: 'DD/MM/YYYY', // 15/01/2024
1767
+ * separator: ' - ',
1768
+ * daysOfWeek: ['Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa', 'Do'],
1769
+ * monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
1770
+ * 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
1771
+ * applyLabel: 'Aplicar',
1772
+ * cancelLabel: 'Cancelar',
1773
+ * firstDay: 1 // Monday first
1774
+ * };
1775
+ *
1776
+ * // US format (MM/DD/YYYY)
1777
+ * const usLocale: NgxDatexLocale = {
1778
+ * locale: 'en-US',
1779
+ * format: 'MM/DD/YYYY', // 01/15/2024
1780
+ * separator: ' - ',
1781
+ * daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
1782
+ * monthNames: ['January', 'February', 'March', 'April', 'May', 'June',
1783
+ * 'July', 'August', 'September', 'October', 'November', 'December'],
1784
+ * applyLabel: 'Apply',
1785
+ * cancelLabel: 'Cancel',
1786
+ * firstDay: 0 // Sunday first
1787
+ * };
1788
+ *
1789
+ * // ISO format (YYYY-MM-DD)
1790
+ * const isoLocale: NgxDatexLocale = {
1791
+ * locale: 'en-US',
1792
+ * format: 'YYYY-MM-DD', // 2024-01-15
1793
+ * separator: ' / ',
1794
+ * daysOfWeek: ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],
1795
+ * monthNames: ['January', 'February', 'March', 'April', 'May', 'June',
1796
+ * 'July', 'August', 'September', 'October', 'November', 'December'],
1797
+ * applyLabel: 'Apply',
1798
+ * cancelLabel: 'Cancel',
1799
+ * firstDay: 1 // Monday first
1800
+ * };
1801
+ * ```
1802
+ *
1803
+ * ### Time Picker Formats:
1550
1804
  * ```typescript
1805
+ * // Spanish with 24-hour time
1806
+ * const spanishWithTime: NgxDatexLocale = {
1807
+ * locale: 'es-ES',
1808
+ * format: 'DD/MM/YYYY HH:mm', // 15/01/2024 14:30
1809
+ * separator: ' - ',
1810
+ * daysOfWeek: ['Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sa', 'Do'],
1811
+ * monthNames: ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio',
1812
+ * 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'],
1813
+ * applyLabel: 'Aplicar',
1814
+ * cancelLabel: 'Cancelar'
1815
+ * };
1816
+ *
1817
+ * // US with 12-hour time
1818
+ * const usWithTime: NgxDatexLocale = {
1819
+ * locale: 'en-US',
1820
+ * format: 'MM/DD/YYYY hh:mm A', // 01/15/2024 02:30 PM
1821
+ * separator: ' - ',
1822
+ * daysOfWeek: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],
1823
+ * monthNames: ['January', 'February', 'March', 'April', 'May', 'June',
1824
+ * 'July', 'August', 'September', 'October', 'November', 'December'],
1825
+ * applyLabel: 'Apply',
1826
+ * cancelLabel: 'Cancel'
1827
+ * };
1828
+ *
1829
+ * // French locale
1551
1830
  * const frenchLocale: NgxDatexLocale = {
1831
+ * locale: 'fr-FR',
1552
1832
  * format: 'DD/MM/YYYY',
1833
+ * separator: ' au ',
1553
1834
  * daysOfWeek: ['Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa', 'Di'],
1835
+ * monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
1836
+ * 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
1554
1837
  * applyLabel: 'Appliquer',
1555
- * cancelLabel: 'Annuler'
1838
+ * cancelLabel: 'Annuler',
1839
+ * customRangeLabel: 'Plage personnalisée',
1840
+ * firstDay: 1
1841
+ * };
1842
+ *
1843
+ * // German locale
1844
+ * const germanLocale: NgxDatexLocale = {
1845
+ * locale: 'de-DE',
1846
+ * format: 'DD.MM.YYYY',
1847
+ * separator: ' bis ',
1848
+ * daysOfWeek: ['Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa', 'So'],
1849
+ * monthNames: ['Januar', 'Februar', 'März', 'April', 'Mai', 'Juni',
1850
+ * 'Juli', 'August', 'September', 'Oktober', 'November', 'Dezember'],
1851
+ * applyLabel: 'Anwenden',
1852
+ * cancelLabel: 'Abbrechen',
1853
+ * customRangeLabel: 'Benutzerdefiniert',
1854
+ * firstDay: 1
1556
1855
  * };
1557
1856
  * ```
1857
+ *
1858
+ * ## Component Usage:
1859
+ * ```html
1860
+ * <!-- Spanish date picker -->
1861
+ * <ngx-datex [locale]="spanishLocale"></ngx-datex>
1862
+ *
1863
+ * <!-- US date picker with time -->
1864
+ * <ngx-datex
1865
+ * [locale]="usWithTime"
1866
+ * [timePicker]="true"
1867
+ * [timePicker24Hour]="false">
1868
+ * </ngx-datex>
1869
+ *
1870
+ * <!-- French date picker -->
1871
+ * <ngx-datex [locale]="frenchLocale"></ngx-datex>
1872
+ *
1873
+ * <!-- Using predefined locales -->
1874
+ * <ngx-datex [locale]="SPANISH_LOCALE"></ngx-datex>
1875
+ * <ngx-datex [locale]="US_ENGLISH_LOCALE"></ngx-datex>
1876
+ * <ngx-datex [locale]="SPANISH_LOCALE_WITH_TIME"></ngx-datex>
1877
+ * ```
1878
+ *
1879
+ * ## Important Notes:
1880
+ *
1881
+ * 1. **TimePicker Format**: When `timePicker=true`, you MUST include time tokens in the format
1882
+ * 2. **Locale Code**: The `locale` property affects @formkit/tempo formatting behavior
1883
+ * 3. **Day Order**: `daysOfWeek` array should match your `firstDay` setting
1884
+ * 4. **Separator**: Used between start and end dates in range display
1885
+ * 5. **Predefined Locales**: Use exported constants like `SPANISH_LOCALE`, `US_ENGLISH_LOCALE`
1886
+ *
1887
+ * @see {@link NgxDatexLocale} for complete interface documentation
1888
+ * @see {@link SPANISH_LOCALE} for default Spanish configuration
1889
+ * @see {@link US_ENGLISH_LOCALE} for US English configuration
1890
+ * @see {@link SPANISH_LOCALE_WITH_TIME} for Spanish with time support
1558
1891
  */
1559
1892
  locale = input(SPANISH_LOCALE, ...(ngDevMode ? [{ debugName: "locale" }] : []));
1560
1893
  /**
@@ -2574,17 +2907,18 @@ class NgxDatex {
2574
2907
  const endDate = this.currentEndDate;
2575
2908
  if (!startDate)
2576
2909
  return '';
2577
- const format = this.locale().format || 'DD/MM/YYYY';
2578
- const timeFormat = this.timePicker() ? (this.timePicker24Hour() ? ' HH:mm' : ' hh:mm A') : '';
2579
- const fullFormat = format + timeFormat;
2580
- const start = formatDateValue(startDate, fullFormat);
2910
+ const locale = this.locale();
2911
+ const format = locale.format || 'DD/MM/YYYY';
2912
+ // Following vanilla-daterangepicker: ALWAYS use locale.format as-is
2913
+ // User must configure format to include time if timePicker is enabled
2914
+ const start = formatDateValue(startDate, format, locale.locale);
2581
2915
  if (this.singleDatePicker()) {
2582
2916
  return start;
2583
2917
  }
2584
2918
  if (!endDate) {
2585
2919
  return start;
2586
2920
  }
2587
- const end = formatDateValue(endDate, fullFormat);
2921
+ const end = formatDateValue(endDate, format, locale.locale);
2588
2922
  return `${start} - ${end}`;
2589
2923
  }, ...(ngDevMode ? [{ debugName: "formattedSelectedRange" }] : []));
2590
2924
  // Current label for selected range
@@ -2597,15 +2931,16 @@ class NgxDatex {
2597
2931
  return '';
2598
2932
  let customRange = true;
2599
2933
  const ranges = this.ranges();
2934
+ const locale = this.locale();
2600
2935
  for (const [label, [rangeStart, rangeEnd]] of Object.entries(ranges)) {
2601
2936
  let startMatches;
2602
2937
  let endMatches;
2603
2938
  if (this.timePicker()) {
2604
2939
  const format = this.timePickerSeconds() ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm';
2605
- const startFormatted = formatDateValue(startDate, format);
2606
- const endFormatted = formatDateValue(endDate, format);
2607
- const rangeStartFormatted = formatDateValue(rangeStart, format);
2608
- const rangeEndFormatted = formatDateValue(rangeEnd, format);
2940
+ const startFormatted = formatDateValue(startDate, format, locale.locale);
2941
+ const endFormatted = formatDateValue(endDate, format, locale.locale);
2942
+ const rangeStartFormatted = formatDateValue(rangeStart, format, locale.locale);
2943
+ const rangeEndFormatted = formatDateValue(rangeEnd, format, locale.locale);
2609
2944
  startMatches = startFormatted === rangeStartFormatted;
2610
2945
  endMatches = endFormatted === rangeEndFormatted;
2611
2946
  }
@@ -2619,7 +2954,7 @@ class NgxDatex {
2619
2954
  }
2620
2955
  }
2621
2956
  if (customRange) {
2622
- return this.locale().customRangeLabel || 'Rango Personalizado';
2957
+ return locale.customRangeLabel || 'Rango Personalizado';
2623
2958
  }
2624
2959
  return '';
2625
2960
  }, ...(ngDevMode ? [{ debugName: "currentLabel" }] : []));
@@ -2629,15 +2964,16 @@ class NgxDatex {
2629
2964
  if (!startDate || !endDate)
2630
2965
  return false;
2631
2966
  const ranges = this.ranges();
2967
+ const locale = this.locale();
2632
2968
  for (const [rangeStart, rangeEnd] of Object.values(ranges)) {
2633
2969
  let startMatches;
2634
2970
  let endMatches;
2635
2971
  if (this.timePicker()) {
2636
2972
  const format = this.timePickerSeconds() ? 'YYYY-MM-DD HH:mm:ss' : 'YYYY-MM-DD HH:mm';
2637
- const startFormatted = formatDateValue(startDate, format);
2638
- const endFormatted = formatDateValue(endDate, format);
2639
- const rangeStartFormatted = formatDateValue(rangeStart, format);
2640
- const rangeEndFormatted = formatDateValue(rangeEnd, format);
2973
+ const startFormatted = formatDateValue(startDate, format, locale.locale);
2974
+ const endFormatted = formatDateValue(endDate, format, locale.locale);
2975
+ const rangeStartFormatted = formatDateValue(rangeStart, format, locale.locale);
2976
+ const rangeEndFormatted = formatDateValue(rangeEnd, format, locale.locale);
2641
2977
  startMatches = startFormatted === rangeStartFormatted;
2642
2978
  endMatches = endFormatted === rangeEndFormatted;
2643
2979
  }
@@ -2711,6 +3047,7 @@ class NgxDatex {
2711
3047
  this.updateMonthsInView();
2712
3048
  }
2713
3049
  if (this.timePicker()) {
3050
+ // Always update time signals from the provided dates to ensure sync
2714
3051
  this.updateTimeSignalsFromDate(value.startDate, 'start');
2715
3052
  if (value.endDate) {
2716
3053
  this.updateTimeSignalsFromDate(value.endDate, 'end');
@@ -2749,6 +3086,7 @@ class NgxDatex {
2749
3086
  * ```
2750
3087
  */
2751
3088
  toggle() {
3089
+ console.log('se ejecuta toggle');
2752
3090
  if (this.disabled() || this.readonly())
2753
3091
  return;
2754
3092
  if (this._isOpen()) {
@@ -2771,12 +3109,13 @@ class NgxDatex {
2771
3109
  openCalendar() {
2772
3110
  if (this.disabled() || this.readonly() || this._isOpen())
2773
3111
  return;
2774
- // Save old values for potential cancellation
3112
+ // Save old values for potential cancellation (following vanilla daterangepicker)
2775
3113
  this.oldStartDate = new Date(this.currentStartDate);
2776
3114
  this.oldEndDate = this.currentEndDate ? new Date(this.currentEndDate) : null;
2777
3115
  this.previousRightTime = this.currentEndDate ? new Date(this.currentEndDate) : null;
2778
3116
  this.createOverlay();
2779
3117
  this._isOpen.set(true);
3118
+ // Sync time signals with current dates when opening (don't modify the dates)
2780
3119
  if (this.timePicker()) {
2781
3120
  this.updateTimeSignalsFromDate(this.currentStartDate, 'start');
2782
3121
  if (this.currentEndDate) {
@@ -2797,17 +3136,24 @@ class NgxDatex {
2797
3136
  * ```
2798
3137
  */
2799
3138
  closeCalendar() {
3139
+ console.log('ouscerrando');
2800
3140
  this._isOpen.set(false);
2801
3141
  this._hoverDate.set(null);
2802
- // Handle incomplete selection
3142
+ console.log(!this.currentEndDate && this.oldStartDate && this.oldEndDate);
3143
+ console.log(this.currentEndDate, this.oldStartDate, this.oldEndDate);
3144
+ // Handle incomplete selection (following vanilla daterangepicker logic)
2803
3145
  if (!this.currentEndDate && this.oldStartDate && this.oldEndDate) {
2804
3146
  this.currentStartDate = this.oldStartDate;
2805
3147
  this.currentEndDate = this.oldEndDate;
2806
3148
  this.updateCurrentValue();
3149
+ return;
2807
3150
  }
3151
+ console.log('segunda vez se ejecuta');
3152
+ // Check for changes using appropriate precision based on timePicker
2808
3153
  if (this.oldStartDate && this.oldEndDate) {
2809
- const hasChanges = !isSameDate(this.currentStartDate, this.oldStartDate, 'day') ||
2810
- (this.currentEndDate && !isSameDate(this.currentEndDate, this.oldEndDate, 'day'));
3154
+ const precision = this.timePicker() ? 'minute' : 'day';
3155
+ const hasChanges = !isSameDate(this.currentStartDate, this.oldStartDate, precision) ||
3156
+ (this.currentEndDate && !isSameDate(this.currentEndDate, this.oldEndDate, precision));
2811
3157
  if (hasChanges && this.currentEndDate) {
2812
3158
  this.emitValueChange();
2813
3159
  }
@@ -2831,6 +3177,33 @@ class NgxDatex {
2831
3177
  apply() {
2832
3178
  if (!this.canApplyValue())
2833
3179
  return;
3180
+ // Ensure time values are applied to the dates before closing
3181
+ if (this.timePicker()) {
3182
+ const startTime = this._startTime();
3183
+ const endTime = this._endTime();
3184
+ // Apply start time
3185
+ let startHour = startTime.hour;
3186
+ if (!this.timePicker24Hour()) {
3187
+ if (startTime.ampm === 'PM' && startHour < 12)
3188
+ startHour += 12;
3189
+ if (startTime.ampm === 'AM' && startHour === 12)
3190
+ startHour = 0;
3191
+ }
3192
+ this.currentStartDate.setHours(startHour, startTime.minute, 0, 0);
3193
+ // Apply end time if exists
3194
+ if (this.currentEndDate) {
3195
+ let endHour = endTime.hour;
3196
+ if (!this.timePicker24Hour()) {
3197
+ if (endTime.ampm === 'PM' && endHour < 12)
3198
+ endHour += 12;
3199
+ if (endTime.ampm === 'AM' && endHour === 12)
3200
+ endHour = 0;
3201
+ }
3202
+ this.currentEndDate.setHours(endHour, endTime.minute, 0, 0);
3203
+ }
3204
+ this.updateCurrentValue();
3205
+ }
3206
+ console.log('apply');
2834
3207
  this.updateElement();
2835
3208
  this.closeCalendar();
2836
3209
  }
@@ -2845,6 +3218,7 @@ class NgxDatex {
2845
3218
  * ```
2846
3219
  */
2847
3220
  cancel() {
3221
+ console.log('calcelll');
2848
3222
  if (this.oldStartDate && this.oldEndDate) {
2849
3223
  this.currentStartDate = this.oldStartDate;
2850
3224
  this.currentEndDate = this.oldEndDate;
@@ -2949,8 +3323,19 @@ class NgxDatex {
2949
3323
  if (!range)
2950
3324
  return;
2951
3325
  const [rangeStart, rangeEnd] = range;
2952
- this.currentStartDate = startOfDay(new Date(rangeStart));
2953
- this.currentEndDate = endOfDay(new Date(rangeEnd));
3326
+ if (this.timePicker()) {
3327
+ // When timePicker is enabled, preserve the exact time from the range
3328
+ this.currentStartDate = new Date(rangeStart);
3329
+ this.currentEndDate = new Date(rangeEnd);
3330
+ // Update time signals to match the selected range
3331
+ this.updateTimeSignalsFromDate(this.currentStartDate, 'start');
3332
+ this.updateTimeSignalsFromDate(this.currentEndDate, 'end');
3333
+ }
3334
+ else {
3335
+ // When timePicker is disabled, use start/end of day
3336
+ this.currentStartDate = startOfDay(new Date(rangeStart));
3337
+ this.currentEndDate = endOfDay(new Date(rangeEnd));
3338
+ }
2954
3339
  this.updateCurrentValue();
2955
3340
  this.updateMonthsInView();
2956
3341
  this.apply();
@@ -2977,6 +3362,7 @@ class NgxDatex {
2977
3362
  this.elementChanged();
2978
3363
  }
2979
3364
  onInputKeydown(event) {
3365
+ console.log('aquuiii');
2980
3366
  if (event.key === 'Enter' || event.key === ' ') {
2981
3367
  event.preventDefault();
2982
3368
  this.toggle();
@@ -3008,6 +3394,7 @@ class NgxDatex {
3008
3394
  }
3009
3395
  onCalendarKeydown(event) {
3010
3396
  if (event.key === 'Escape' && !this._inputFocused()) {
3397
+ console.log('close outside');
3011
3398
  this.closeCalendar();
3012
3399
  }
3013
3400
  }
@@ -3294,26 +3681,63 @@ class NgxDatex {
3294
3681
  }
3295
3682
  initializeDefaultDates() {
3296
3683
  const today = new Date();
3684
+ // Following vanilla daterangepicker: always start with startOf/endOf day
3685
+ // moment().startOf('day') = 00:00:00
3686
+ // moment().endOf('day') = 23:59:59
3297
3687
  const startDate = startOfDay(today);
3298
3688
  const endDate = this.singleDatePicker() ? startOfDay(today) : endOfDay(today);
3689
+ // When timePicker is enabled, preserve these default times
3690
+ // (vanilla daterangepicker doesn't modify them when timePicker=true)
3691
+ if (this.timePicker()) {
3692
+ // Initialize time signals from the default dates
3693
+ this.updateTimeSignalsFromDate(startDate, 'start');
3694
+ if (endDate) {
3695
+ this.updateTimeSignalsFromDate(endDate, 'end');
3696
+ }
3697
+ }
3299
3698
  this.currentStartDate = startDate;
3300
3699
  this.currentEndDate = endDate;
3301
3700
  this.initializeCalendars(startDate, endDate);
3302
3701
  this.updateCurrentValue();
3303
- if (this.timePicker()) {
3304
- this.updateTimeSignalsFromDate(today, 'start');
3305
- this.updateTimeSignalsFromDate(today, 'end');
3306
- }
3307
3702
  }
3308
3703
  initializeWithInputDates(inputStartDate, inputEndDate) {
3309
- const startDate = inputStartDate
3310
- ? startOfDay(new Date(inputStartDate))
3311
- : startOfDay(new Date());
3312
- const endDate = this.singleDatePicker()
3313
- ? startDate
3314
- : inputEndDate
3315
- ? endOfDay(new Date(inputEndDate))
3316
- : endOfDay(startDate);
3704
+ let startDate;
3705
+ let endDate;
3706
+ if (this.timePicker()) {
3707
+ // When timePicker is enabled, preserve the full date-time or use appropriate defaults
3708
+ if (inputStartDate) {
3709
+ startDate = new Date(inputStartDate);
3710
+ // If the input date doesn't have specific time (is at 00:00:00), keep it as is
3711
+ // Otherwise preserve the provided time
3712
+ }
3713
+ else {
3714
+ startDate = new Date();
3715
+ startDate.setHours(0, 0, 0, 0); // Default start time: 00:00
3716
+ }
3717
+ if (this.singleDatePicker()) {
3718
+ endDate = new Date(startDate);
3719
+ }
3720
+ else if (inputEndDate) {
3721
+ endDate = new Date(inputEndDate);
3722
+ // If the input end date doesn't have specific time (is at 00:00:00), set to end of day
3723
+ if (endDate.getHours() === 0 && endDate.getMinutes() === 0 && endDate.getSeconds() === 0) {
3724
+ endDate.setHours(23, 59, 0, 0);
3725
+ }
3726
+ }
3727
+ else {
3728
+ endDate = new Date(startDate);
3729
+ endDate.setHours(23, 59, 0, 0); // Default end time: 23:59
3730
+ }
3731
+ }
3732
+ else {
3733
+ // When timePicker is disabled, use start/end of day
3734
+ startDate = inputStartDate ? startOfDay(new Date(inputStartDate)) : startOfDay(new Date());
3735
+ endDate = this.singleDatePicker()
3736
+ ? new Date(startDate)
3737
+ : inputEndDate
3738
+ ? endOfDay(new Date(inputEndDate))
3739
+ : endOfDay(startDate);
3740
+ }
3317
3741
  this.currentStartDate = startDate;
3318
3742
  this.currentEndDate = endDate;
3319
3743
  this.initializeCalendars(startDate, endDate);
@@ -3372,7 +3796,7 @@ class NgxDatex {
3372
3796
  }
3373
3797
  }
3374
3798
  setStartDate(startDate) {
3375
- const newStartDate = this.calendarService.setStartDate(startDate, this.minDate(), this.maxDate(), this.timePicker(), this.timePickerIncrement());
3799
+ const newStartDate = this.calendarService.setStartDate(startDate, this.minDate(), this.maxDate(), this.timePicker(), this.timePickerIncrement(), this.currentStartDate);
3376
3800
  this.currentStartDate = newStartDate;
3377
3801
  this.updateCurrentValue();
3378
3802
  this.updateMonthsInView();
@@ -3381,7 +3805,7 @@ class NgxDatex {
3381
3805
  }
3382
3806
  }
3383
3807
  setEndDate(endDate) {
3384
- const newEndDate = this.calendarService.setEndDate(endDate, this.currentStartDate, this.maxDate(), this.maxSpan(), this.timePicker(), this.timePickerIncrement());
3808
+ const newEndDate = this.calendarService.setEndDate(endDate, this.currentStartDate, this.maxDate(), this.maxSpan(), this.timePicker(), this.timePickerIncrement(), this.currentEndDate);
3385
3809
  this.previousRightTime = new Date(newEndDate);
3386
3810
  this.currentEndDate = newEndDate;
3387
3811
  this.updateCurrentValue();
@@ -3397,13 +3821,14 @@ class NgxDatex {
3397
3821
  const endDate = this._internalEndDate;
3398
3822
  if (!startDate)
3399
3823
  return;
3400
- const format = this.locale().format || 'DD/MM/YYYY';
3401
- const timeFormat = this.timePicker() ? (this.timePicker24Hour() ? ' HH:mm' : ' hh:mm A') : '';
3402
- const fullFormat = format + timeFormat;
3403
- const separator = this.locale().separator || ' - ';
3404
- let newValue = formatDateValue(startDate, fullFormat);
3824
+ const locale = this.locale();
3825
+ const format = locale.format || 'DD/MM/YYYY';
3826
+ const separator = locale.separator || ' - ';
3827
+ // Following vanilla-daterangepicker: ALWAYS use locale.format as-is
3828
+ // User must configure format to include time if timePicker is enabled
3829
+ let newValue = formatDateValue(startDate, format, locale.locale);
3405
3830
  if (!this.singleDatePicker() && endDate) {
3406
- newValue += separator + formatDateValue(endDate, fullFormat);
3831
+ newValue += separator + formatDateValue(endDate, format, locale.locale);
3407
3832
  }
3408
3833
  this._displayValue.set(newValue);
3409
3834
  }
@@ -3412,6 +3837,7 @@ class NgxDatex {
3412
3837
  startDate: this.currentStartDate,
3413
3838
  endDate: this.currentEndDate,
3414
3839
  };
3840
+ console.log(value, 'updateCurrentValue ');
3415
3841
  this._currentValue.set(value);
3416
3842
  }
3417
3843
  emitValueChange() {
@@ -3459,7 +3885,9 @@ class NgxDatex {
3459
3885
  const dateString = inputValue.split(separator);
3460
3886
  let start = null;
3461
3887
  let end = null;
3888
+ console.log(dateString);
3462
3889
  if (dateString.length === 2) {
3890
+ console.log(this.parseInputDate(dateString[1].trim()));
3463
3891
  start = this.parseInputDate(dateString[0].trim());
3464
3892
  end = this.parseInputDate(dateString[1].trim());
3465
3893
  }
@@ -3487,9 +3915,11 @@ class NgxDatex {
3487
3915
  parseInputDate(dateStr) {
3488
3916
  if (!dateStr)
3489
3917
  return null;
3490
- const format = this.locale().format || 'DD/MM/YYYY';
3918
+ const locale = this.locale();
3919
+ console.log(locale);
3920
+ const format = locale.format || 'DD/MM/YYYY';
3491
3921
  try {
3492
- const date = parseDateValue(dateStr, format);
3922
+ const date = parseDateValue(dateStr, format, locale.locale);
3493
3923
  if (isValidDate(date)) {
3494
3924
  return date;
3495
3925
  }
@@ -3558,5 +3988,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.1", ngImpor
3558
3988
  * Generated bundle index. Do not edit.
3559
3989
  */
3560
3990
 
3561
- export { DEFAULT_RANGES, MATERIAL_LIGHT_THEME, NgxDatex, NgxDatexCalendarService, NgxDatexOverlayService, NgxDatexService, NgxDatexTimePickerService, SPANISH_LOCALE, addDays, addMonths, endOfDay, formatDateValue, getStartOfMonth, getStartOfWeek, isBeforeDate, isMobileDevice, isSameDate, isSameDay, isSameMonth, isSameYear, isValidDate, parseDateValue, startOfDay, startOfMonth, startOfWeek };
3991
+ export { DEFAULT_RANGES, ISO_LOCALE, ISO_LOCALE_WITH_TIME, MATERIAL_LIGHT_THEME, NgxDatex, NgxDatexCalendarService, NgxDatexOverlayService, NgxDatexService, NgxDatexTimePickerService, SPANISH_LOCALE, SPANISH_LOCALE_WITH_TIME, SPANISH_LOCALE_WITH_TIME_12H, US_ENGLISH_LOCALE, US_ENGLISH_LOCALE_WITH_TIME, addDays, addMonths, endOfDay, formatDateValue, getStartOfMonth, getStartOfWeek, isBeforeDate, isMobileDevice, isSameDate, isSameDay, isSameMonth, isSameYear, isValidDate, parseDateValue, startOfDay, startOfMonth, startOfWeek };
3562
3992
  //# sourceMappingURL=ngx-datex.mjs.map