datex-ui 1.0.7 → 1.1.9

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.
package/dist/index.esm.js CHANGED
@@ -1,65 +1,77 @@
1
- function v(c, t) {
2
- const e = c.getFullYear(), i = String(c.getMonth() + 1).padStart(2, "0"), a = String(c.getDate()).padStart(2, "0"), n = String(c.getHours()).padStart(2, "0"), o = String(c.getMinutes()).padStart(2, "0"), r = String(c.getSeconds()).padStart(2, "0");
3
- return t.replace(/YYYY/g, String(e)).replace(/MM/g, i).replace(/DD/g, a).replace(/HH/g, n).replace(/mm/g, o).replace(/ss/g, r);
1
+ function C(l, t) {
2
+ const e = l.getFullYear(), a = String(l.getMonth() + 1).padStart(2, "0"), i = String(l.getDate()).padStart(2, "0"), s = String(l.getHours()).padStart(2, "0"), r = String(l.getMinutes()).padStart(2, "0"), n = String(l.getSeconds()).padStart(2, "0");
3
+ return t.replace(/YYYY/g, String(e)).replace(/MM/g, a).replace(/DD/g, i).replace(/HH/g, s).replace(/mm/g, r).replace(/ss/g, n);
4
4
  }
5
- function $(c, t) {
6
- const e = new Date(c);
7
- return e.setDate(e.getDate() + t), e;
8
- }
9
- function y(c, t) {
10
- const e = new Date(c);
5
+ function f(l, t) {
6
+ const e = new Date(l);
11
7
  return e.setMonth(e.getMonth() + t), e;
12
8
  }
13
- function M(c) {
14
- const t = new Date(c);
9
+ function w(l) {
10
+ const t = new Date(l);
15
11
  return t.setHours(0, 0, 0, 0), t;
16
12
  }
17
- function E(c) {
18
- const t = new Date(c);
13
+ function S(l) {
14
+ const t = new Date(l);
19
15
  return t.setHours(23, 59, 59, 999), t;
20
16
  }
21
- function b(c, t) {
22
- return c.getTime() > t.getTime();
17
+ function k(l, t) {
18
+ return l.getTime() > t.getTime();
19
+ }
20
+ function g(l, t) {
21
+ return l.getTime() < t.getTime();
22
+ }
23
+ function u(l, t, e = "day") {
24
+ if (!l || !t) return !1;
25
+ switch (e) {
26
+ case "day":
27
+ return l.getFullYear() === t.getFullYear() && l.getMonth() === t.getMonth() && l.getDate() === t.getDate();
28
+ case "month":
29
+ return l.getFullYear() === t.getFullYear() && l.getMonth() === t.getMonth();
30
+ case "year":
31
+ return l.getFullYear() === t.getFullYear();
32
+ default:
33
+ return !1;
34
+ }
23
35
  }
24
- function g(c, t) {
25
- return c.getTime() < t.getTime();
36
+ function y(l) {
37
+ return l instanceof Date && !isNaN(l.getTime());
26
38
  }
27
- function C(c, t) {
28
- if (t === "YYYY-MM-DD")
29
- return new Date(c);
39
+ function b(l, t) {
40
+ if (t === "YYYY-MM-DD") {
41
+ const e = l.split("-");
42
+ if (e.length === 3) {
43
+ const a = parseInt(e[0], 10), i = parseInt(e[1], 10) - 1, s = parseInt(e[2], 10);
44
+ return new Date(a, i, s);
45
+ }
46
+ return new Date(l);
47
+ }
30
48
  if (t === "DD/MM/YYYY") {
31
- const e = c.split("/");
49
+ const e = l.split("/");
32
50
  if (e.length === 3) {
33
- const i = parseInt(e[0], 10), a = parseInt(e[1], 10) - 1, n = parseInt(e[2], 10);
34
- return new Date(n, a, i);
51
+ const a = parseInt(e[0], 10), i = parseInt(e[1], 10) - 1, s = parseInt(e[2], 10);
52
+ return new Date(s, i, a);
35
53
  }
36
54
  }
37
55
  if (t === "DD/MM/YYYY HH:mm") {
38
- const [e, i] = c.split(" "), a = e.split("/"), n = i ? i.split(":") : ["0", "0"];
39
- if (a.length === 3) {
40
- const o = parseInt(a[0], 10), r = parseInt(a[1], 10) - 1, f = parseInt(a[2], 10), h = parseInt(n[0], 10) || 0, d = parseInt(n[1], 10) || 0;
41
- return new Date(f, r, o, h, d);
56
+ const [e, a] = l.split(" "), i = e.split("/"), s = a ? a.split(":") : ["0", "0"];
57
+ if (i.length === 3) {
58
+ const r = parseInt(i[0], 10), n = parseInt(i[1], 10) - 1, o = parseInt(i[2], 10), c = parseInt(s[0], 10) || 0, d = parseInt(s[1], 10) || 0;
59
+ return new Date(o, n, r, c, d);
42
60
  }
43
61
  }
44
- return new Date(c);
62
+ return new Date(l);
45
63
  }
46
- function x(c, t, e = "day") {
47
- if (!c || !t) return !1;
48
- switch (e) {
49
- case "day":
50
- return c.getFullYear() === t.getFullYear() && c.getMonth() === t.getMonth() && c.getDate() === t.getDate();
51
- case "month":
52
- return c.getFullYear() === t.getFullYear() && c.getMonth() === t.getMonth();
53
- case "year":
54
- return c.getFullYear() === t.getFullYear();
55
- default:
56
- return !1;
57
- }
64
+ function x(l) {
65
+ return new Date(l.getFullYear(), l.getMonth(), 1);
58
66
  }
59
- function S(c) {
60
- return c instanceof Date && !isNaN(c.getTime());
67
+ function L(l) {
68
+ return new Date(l.getFullYear(), l.getMonth() + 1, 0);
61
69
  }
62
- const L = {
70
+ function $(l, t = 1) {
71
+ const a = (l.getDay() - t + 7) % 7, i = new Date(l);
72
+ return i.setDate(l.getDate() - a), i;
73
+ }
74
+ const E = {
63
75
  primaryColor: "#357ebd",
64
76
  secondaryColor: "#ccc",
65
77
  backgroundColor: "#ffffff",
@@ -75,7 +87,7 @@ const L = {
75
87
  borderRadius: "4px",
76
88
  fontSize: "15px",
77
89
  fontFamily: "arial"
78
- }, I = {
90
+ }, B = {
79
91
  primaryColor: "#0d6efd",
80
92
  secondaryColor: "#6c757d",
81
93
  backgroundColor: "#ffffff",
@@ -91,7 +103,7 @@ const L = {
91
103
  borderRadius: "6px",
92
104
  fontSize: "14px",
93
105
  fontFamily: 'system-ui, -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif'
94
- }, T = {
106
+ }, R = {
95
107
  primaryColor: "#1976d2",
96
108
  secondaryColor: "#757575",
97
109
  backgroundColor: "#ffffff",
@@ -107,86 +119,81 @@ const L = {
107
119
  borderRadius: "4px",
108
120
  fontSize: "14px",
109
121
  fontFamily: 'Roboto, "Helvetica Neue", Arial, sans-serif'
110
- }, Y = {
111
- format: "DD/MM/YYYY",
112
- separator: " - ",
113
- applyLabel: "Aplicar",
114
- cancelLabel: "Cancelar",
115
- customRangeLabel: "Rango Personalizado",
116
- daysOfWeek: ["Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"],
117
- monthNames: [
118
- "Enero",
119
- "Febrero",
120
- "Marzo",
121
- "Abril",
122
- "Mayo",
123
- "Junio",
124
- "Julio",
125
- "Agosto",
126
- "Septiembre",
127
- "Octubre",
128
- "Noviembre",
129
- "Diciembre"
130
- ],
131
- firstDay: 1
132
- // Monday
133
- }, A = {
134
- format: "DD/MM/YYYY HH:mm",
135
- separator: " - ",
136
- applyLabel: "Aplicar",
137
- cancelLabel: "Cancelar",
138
- customRangeLabel: "Rango Personalizado",
139
- daysOfWeek: ["Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"],
140
- monthNames: [
141
- "Enero",
142
- "Febrero",
143
- "Marzo",
144
- "Abril",
145
- "Mayo",
146
- "Junio",
147
- "Julio",
148
- "Agosto",
149
- "Septiembre",
150
- "Octubre",
151
- "Noviembre",
152
- "Diciembre"
153
- ],
154
- firstDay: 1
155
- // Monday
156
122
  };
157
- class q {
158
- constructor(t, e = {}, i) {
159
- if (this.boundHandlers = /* @__PURE__ */ new Map(), this.element = typeof t == "string" ? (t.startsWith("#") ? document.getElementById(t.slice(1)) : document.querySelector(t)) || document.getElementById(t) : t, !this.element)
160
- throw new Error("Datex: Element not found");
161
- this.options = this.mergeOptions(e), this.locale = this.options.locale, this.theme = { ...this.options.theme }, this.callback = i || (() => {
162
- });
163
- const a = /* @__PURE__ */ new Date();
164
- this.state = {
165
- startDate: this.options.timePicker ? this.options.startDate : M(this.options.startDate),
166
- endDate: this.options.timePicker ? this.options.endDate : E(this.options.endDate),
167
- oldStartDate: this.options.timePicker ? this.options.startDate : M(this.options.startDate),
168
- oldEndDate: this.options.timePicker ? this.options.endDate : E(this.options.endDate),
169
- isShowing: !1,
170
- leftCalendar: { month: a, calendar: [] },
171
- rightCalendar: { month: y(a, 1), calendar: [] },
172
- chosenLabel: null,
173
- hoverDate: null
174
- }, this.createContainer(), this.setupEventListeners(), this.updateElement(), this.calculateChosenLabel(), this.applyTheme();
123
+ class T {
124
+ constructor(t, e = E) {
125
+ this.mode = "light", this.handleMediaChange = () => {
126
+ this.mode === "auto" && this.applyTheme();
127
+ }, this.container = t, this.theme = { ...E, ...e }, this.setupMediaQueryListener();
175
128
  }
176
129
  applyTheme() {
177
- if (!this.container)
178
- return;
179
- const t = this.container.dataset.themeStyleId;
180
- if (t) {
181
- const a = document.getElementById(t);
182
- a && a.remove();
130
+ this.removeExistingStyles(), this.createAndApplyStyles(), this.forceReflow();
131
+ }
132
+ setTheme(t) {
133
+ this.theme = { ...E, ...t }, this.applyTheme();
134
+ }
135
+ setMode(t) {
136
+ this.mode = t, this.applyTheme();
137
+ }
138
+ getMode() {
139
+ return this.mode;
140
+ }
141
+ getCurrentMode() {
142
+ var t;
143
+ return this.mode === "auto" ? (t = this.mediaQuery) != null && t.matches ? "dark" : "light" : this.mode === "dark" ? "dark" : "light";
144
+ }
145
+ cleanup() {
146
+ this.removeExistingStyles(), this.mediaQuery && this.mediaQuery.removeEventListener("change", this.handleMediaChange);
147
+ }
148
+ setupMediaQueryListener() {
149
+ this.mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"), this.mediaQuery.addEventListener("change", this.handleMediaChange);
150
+ }
151
+ getThemeForMode() {
152
+ return this.getCurrentMode() === "dark" ? {
153
+ ...this.theme,
154
+ backgroundColor: "#1f2937",
155
+ // Fondo oscuro
156
+ borderColor: "#4b5563",
157
+ // Bordes grises oscuros
158
+ textColor: "#f9fafb",
159
+ // Texto blanco/claro
160
+ hoverColor: "#4b5563",
161
+ // Hover gris más claro para mejor contraste
162
+ // Mantener colores originales del tema para selected, range, etc.
163
+ selectedColor: this.theme.selectedColor,
164
+ // Mantener color original
165
+ rangeColor: this.theme.rangeColor,
166
+ // Mantener color original
167
+ todayColor: this.theme.todayColor,
168
+ // Mantener color original
169
+ disabledColor: "#6b7280",
170
+ // Gris para deshabilitado
171
+ applyButtonColor: this.theme.applyButtonColor,
172
+ // Mantener color original
173
+ cancelButtonColor: this.theme.cancelButtonColor
174
+ // Mantener color original
175
+ } : this.theme;
176
+ }
177
+ removeExistingStyles() {
178
+ if (this.styleId) {
179
+ const t = document.getElementById(this.styleId);
180
+ t == null || t.remove();
183
181
  }
184
- const e = "daterangepicker-theme-" + Math.random().toString(36).slice(2, 9), i = document.createElement("style");
185
- i.id = e, i.textContent = this.generateThemeCSS(), document.head.appendChild(i), this.container.dataset.themeStyleId = e, this.container.offsetHeight;
182
+ }
183
+ createAndApplyStyles() {
184
+ this.styleId = this.generateStyleId();
185
+ const t = document.createElement("style");
186
+ t.id = this.styleId, t.textContent = this.generateThemeCSS(), document.head.appendChild(t), this.container.dataset.themeStyleId = this.styleId;
187
+ }
188
+ generateStyleId() {
189
+ return "daterangepicker-theme-" + Math.random().toString(36).slice(2, 9);
190
+ }
191
+ forceReflow() {
192
+ this.container.offsetHeight;
186
193
  }
187
194
  generateThemeCSS() {
188
- const t = this.theme;
189
- return `
195
+ const t = this.getThemeForMode(), e = this.getCurrentMode();
196
+ return this.container.classList.remove("datex-light", "datex-dark"), this.container.classList.add(`datex-${e}`), `
190
197
  .datex-picker {
191
198
  background-color: ${t.backgroundColor} !important;
192
199
  border: 1px solid ${t.borderColor} !important;
@@ -199,7 +206,26 @@ class q {
199
206
  z-index: 3001 !important;
200
207
  }
201
208
 
202
- /* IMPORTANTE: Permitir interacción con selectores */
209
+ .datex-picker.single {
210
+ width: 230px !important;
211
+ }
212
+
213
+ .datex-picker.single .drp-calendar.right {
214
+ display: none !important;
215
+ }
216
+
217
+ .datex-picker.single .drp-calendar.left {
218
+ float: none !important;
219
+ clear: none !important;
220
+ }
221
+
222
+ .datex-picker.single .drp-calendar.left .calendar-table {
223
+ border-right: 1px solid ${t.borderColor} !important;
224
+ border-top-right-radius: ${t.borderRadius} !important;
225
+ border-bottom-right-radius: ${t.borderRadius} !important;
226
+ padding-right: 8px !important;
227
+ }
228
+
203
229
  .datex-picker select,
204
230
  .datex-picker select * {
205
231
  user-select: auto !important;
@@ -253,12 +279,13 @@ class q {
253
279
  .datex-picker .calendar-table th.month {
254
280
  color: ${t.textColor} !important;
255
281
  width: auto !important;
282
+ pointer-events: auto !important;
256
283
  }
257
284
 
258
285
  .datex-picker .calendar-table .next span,
259
286
  .datex-picker .calendar-table .prev span {
260
287
  color: #fff !important;
261
- border: solid black !important;
288
+ border: solid ${e === "dark" ? t.textColor : "black"} !important;
262
289
  border-width: 0 2px 2px 0 !important;
263
290
  border-radius: 0 !important;
264
291
  display: inline-block !important;
@@ -285,13 +312,18 @@ class q {
285
312
 
286
313
  .datex-picker .calendar-table .next:hover,
287
314
  .datex-picker .calendar-table .prev:hover {
288
- background-color: #f0f0f0 !important;
315
+ background-color: ${e === "dark" ? t.hoverColor : "#f0f0f0"} !important;
289
316
  }
290
317
 
291
318
  .datex-picker td.available:hover,
292
319
  .datex-picker th.available:hover {
293
- background-color: #eee !important;
320
+ background-color: ${e === "dark" ? "#4b5563" : "#eee"} !important;
294
321
  border-color: transparent !important;
322
+ color: ${e === "dark" ? "#ffffff" : "#000000"} !important;
323
+ }
324
+
325
+ .datex-picker td.available,
326
+ .datex-picker th.available {
295
327
  color: ${t.textColor} !important;
296
328
  }
297
329
 
@@ -311,21 +343,21 @@ class q {
311
343
  }
312
344
 
313
345
  .datex-picker td.in-range {
314
- background-color: #ebf4f8 !important;
346
+ background-color: ${t.rangeColor} !important;
315
347
  border-color: transparent !important;
316
- color: #000 !important;
348
+ color: #000000 !important;
317
349
  border-radius: 0 !important;
318
350
  }
319
351
 
320
352
  .datex-picker td.start-date {
321
353
  border-radius: 3px 0 0 3px !important;
322
- background-color: #357ebd !important;
354
+ background-color: ${t.selectedColor} !important;
323
355
  color: #fff !important;
324
356
  }
325
357
 
326
358
  .datex-picker td.end-date {
327
359
  border-radius: 0 3px 3px 0 !important;
328
- background-color: #357ebd !important;
360
+ background-color: ${t.selectedColor} !important;
329
361
  color: #fff !important;
330
362
  }
331
363
 
@@ -335,7 +367,7 @@ class q {
335
367
 
336
368
  .datex-picker td.active,
337
369
  .datex-picker td.active:hover {
338
- background-color: #357ebd !important;
370
+ background-color: ${t.selectedColor} !important;
339
371
  border-color: transparent !important;
340
372
  color: #fff !important;
341
373
  }
@@ -404,7 +436,7 @@ class q {
404
436
  .datex-picker .drp-buttons {
405
437
  clear: both !important;
406
438
  text-align: right !important;
407
- padding: 2px !important;
439
+ padding: 8px !important;
408
440
  border-top: 1px solid ${t.borderColor} !important;
409
441
  display: none !important;
410
442
  line-height: 10px !important;
@@ -454,15 +486,6 @@ class q {
454
486
  opacity: 0.8 !important;
455
487
  }
456
488
 
457
- /* Asegurar que el contenedor no bloquee eventos */
458
- .datex-picker .calendar-table th.month {
459
- pointer-events: auto !important;
460
- }
461
-
462
- .datex-picker .calendar-table th.month * {
463
- pointer-events: auto !important;
464
- }
465
-
466
489
  .datex-picker select.monthselect,
467
490
  .datex-picker select.yearselect {
468
491
  font-size: 12px !important;
@@ -474,24 +497,18 @@ class q {
474
497
  border: 1px solid ${t.borderColor} !important;
475
498
  color: ${t.textColor} !important;
476
499
  outline: none !important;
477
- /* Asegurar que los dropdowns funcionen nativamente */
478
500
  appearance: auto !important;
479
501
  -webkit-appearance: menulist !important;
480
502
  -moz-appearance: menulist !important;
481
- /* Permitir interacción */
482
503
  pointer-events: auto !important;
483
504
  user-select: auto !important;
484
505
  -webkit-user-select: auto !important;
485
506
  -moz-user-select: auto !important;
486
- /* Tamaño mínimo para ser clickeable */
487
507
  min-height: 20px !important;
488
508
  min-width: 50px !important;
489
- /* Asegurar que estén por encima de otros elementos */
490
509
  position: relative !important;
491
510
  z-index: 1000000 !important;
492
- /* Remover cualquier transformación que pueda interferir */
493
511
  transform: none !important;
494
- /* Asegurar que no estén bloqueados por overlay */
495
512
  isolation: auto !important;
496
513
  }
497
514
 
@@ -529,13 +546,12 @@ class q {
529
546
 
530
547
  .datex-picker .calendar-time {
531
548
  text-align: center !important;
532
- margin: 4px auto 0 auto !important;
533
- line-height: 30px !important;
549
+ margin: 0 auto !important;
550
+ line-height: 24px !important;
534
551
  position: relative !important;
535
552
  display: block !important;
536
553
  background: ${t.backgroundColor} !important;
537
- padding: 8px !important;
538
- border-top: 1px solid ${t.borderColor} !important;
554
+ padding: 4px 8px !important;
539
555
  }
540
556
 
541
557
  .datex-picker .calendar-time select.disabled {
@@ -560,7 +576,6 @@ class q {
560
576
  color: #fff !important;
561
577
  }
562
578
 
563
- /* Media queries para responsive - exactamente como el CSS original */
564
579
  @media (min-width: 564px) {
565
580
  .datex-picker {
566
581
  width: auto !important;
@@ -614,703 +629,1263 @@ class q {
614
629
  }
615
630
  `;
616
631
  }
617
- // Public method to change theme dynamically
618
- setTheme(t) {
619
- this.theme = { ...L, ...t }, this.applyTheme();
632
+ }
633
+ class A {
634
+ constructor() {
635
+ this.boundHandlers = /* @__PURE__ */ new Map();
636
+ }
637
+ addEventHandler(t, e, a) {
638
+ const i = `${e}_${Math.random()}`;
639
+ this.boundHandlers.set(i, a), t.addEventListener(e, a);
640
+ }
641
+ setDocumentListeners(t, e) {
642
+ this.documentClickHandler = t, this.documentFocusHandler = e, document.addEventListener("mousedown", this.documentClickHandler, !0), document.addEventListener("focusin", this.documentFocusHandler, !0);
643
+ }
644
+ setWindowListeners(t, e) {
645
+ this.resizeHandler = t, this.scrollHandler = e, window.addEventListener("resize", this.resizeHandler), window.addEventListener("scroll", this.scrollHandler, !0);
646
+ }
647
+ removeDocumentListeners() {
648
+ this.documentClickHandler && (document.removeEventListener(
649
+ "mousedown",
650
+ this.documentClickHandler,
651
+ !0
652
+ ), this.documentClickHandler = void 0), this.documentFocusHandler && (document.removeEventListener("focusin", this.documentFocusHandler, !0), this.documentFocusHandler = void 0);
620
653
  }
621
- // Public method to force theme reapplication
622
- refreshTheme() {
623
- this.applyTheme();
654
+ removeWindowListeners() {
655
+ this.resizeHandler && (window.removeEventListener("resize", this.resizeHandler), this.resizeHandler = void 0), this.scrollHandler && (window.removeEventListener("scroll", this.scrollHandler, !0), this.scrollHandler = void 0);
624
656
  }
625
- // Debug method to check current theme
626
- getCurrentTheme() {
627
- return this.theme;
657
+ cleanup() {
658
+ this.removeDocumentListeners(), this.removeWindowListeners(), this.boundHandlers.clear();
628
659
  }
629
- // Debug method to test dropdowns
630
- testDropdowns() {
631
- this.container.querySelectorAll("select").forEach((e, i) => {
632
- e.addEventListener("click", () => {
633
- }), e.click();
660
+ dispatchEvent(t, e, a) {
661
+ const i = new CustomEvent(e, {
662
+ bubbles: !0,
663
+ detail: a
634
664
  });
665
+ t.dispatchEvent(i);
635
666
  }
636
- mergeOptions(t) {
637
- const e = /* @__PURE__ */ new Date(), i = {
638
- startDate: t.startDate || e,
639
- endDate: t.endDate || e,
640
- minDate: t.minDate ?? null,
641
- maxDate: t.maxDate ?? null,
642
- minYear: t.minYear ?? e.getFullYear() - 100,
643
- maxYear: t.maxYear ?? e.getFullYear() + 100,
644
- maxSpan: t.maxSpan ?? null,
645
- autoApply: t.autoApply ?? !1,
646
- singleDatePicker: t.singleDatePicker ?? !1,
647
- showDropdowns: t.showDropdowns ?? !0,
648
- linkedCalendars: t.linkedCalendars ?? !0,
649
- autoUpdateInput: t.autoUpdateInput ?? !0,
650
- alwaysShowCalendars: t.alwaysShowCalendars ?? !1,
651
- showCustomRangeLabel: t.showCustomRangeLabel ?? !0,
652
- timePicker: t.timePicker ?? !1,
653
- timePicker24Hour: t.timePicker24Hour ?? !0,
654
- timePickerIncrement: t.timePickerIncrement ?? 1,
655
- timePickerSeconds: t.timePickerSeconds ?? !1,
656
- ranges: t.ranges || {},
657
- opens: t.opens || "center",
658
- drops: t.drops || "auto",
659
- locale: t.locale || Y,
660
- buttonClasses: t.buttonClasses || "btn btn-sm",
661
- applyButtonClasses: t.applyButtonClasses || "btn-success",
662
- cancelButtonClasses: t.cancelButtonClasses || "btn-danger",
663
- theme: t.theme || L
664
- };
665
- return i.timePicker && i.autoApply && (i.autoApply = !1), i;
667
+ }
668
+ class F {
669
+ constructor(t, e, a) {
670
+ this.element = t, this.container = e, this.options = a;
666
671
  }
667
- createContainer() {
668
- const t = `
669
- <div class="datex-picker">
670
- <div class="ranges"></div>
671
- <div class="drp-calendar left">
672
- <div class="calendar-table"></div>
673
- <div class="calendar-time"></div>
674
- </div>
675
- <div class="drp-calendar right">
676
- <div class="calendar-table"></div>
677
- <div class="calendar-time"></div>
678
- </div>
679
- <div class="drp-buttons">
680
- <span class="drp-selected"></span>
681
- <button class="cancelBtn ${this.options.buttonClasses} ${this.options.cancelButtonClasses}" type="button">
682
- ${this.locale.cancelLabel}
683
- </button>
684
- <button class="applyBtn ${this.options.buttonClasses} ${this.options.applyButtonClasses}" type="button">
685
- ${this.locale.applyLabel}
686
- </button>
687
- </div>
688
- </div>
689
- `, e = document.createElement("div");
690
- e.innerHTML = t.trim(), this.container = e.firstElementChild, document.body.appendChild(this.container), this.container.classList.add(`opens${this.options.opens}`), this.options.singleDatePicker && this.container.classList.add("single"), this.options.autoApply && this.container.classList.add("auto-apply"), Object.keys(this.options.ranges).length > 0 && (this.container.classList.add("show-ranges"), this.renderRanges()), (this.options.alwaysShowCalendars || Object.keys(this.options.ranges).length === 0) && this.container.classList.add("show-calendar"), this.options.autoApply || this.container.classList.add("show-calendar"), this.options.timePicker || this.container.querySelectorAll(".calendar-time").forEach((a) => {
691
- a.style.display = "none";
692
- }), this.container.style.display = "none";
672
+ calculatePosition() {
673
+ if (!this.container) return;
674
+ (window.innerWidth <= 768 || "ontouchstart" in window) && this.container.classList.contains("touch-enabled") ? this.positionForMobile() : this.positionForDesktop();
693
675
  }
694
- renderRanges() {
695
- const t = this.container.querySelector(".ranges");
696
- let e = "<ul>";
697
- for (const [i] of Object.entries(this.options.ranges))
698
- e += `<li data-range-key="${i}">${i}</li>`;
699
- this.options.showCustomRangeLabel && (e += `<li data-range-key="${this.locale.customRangeLabel}">${this.locale.customRangeLabel}</li>`), e += "</ul>", t.innerHTML = e;
676
+ positionForMobile() {
677
+ this.container.style.position = "fixed", this.container.style.bottom = "0", this.container.style.left = "0", this.container.style.right = "0", this.container.style.top = "auto", this.container.style.width = "100%", this.container.style.maxWidth = "100vw", this.container.style.borderRadius = "16px 16px 0 0", this.container.style.zIndex = "99999", this.container.classList.add("drop-up");
700
678
  }
701
- setupEventListeners() {
702
- this.element.tagName === "INPUT" || this.element.tagName === "BUTTON" ? (this.addEventHandler(this.element, "click", this.show.bind(this)), this.addEventHandler(this.element, "focus", this.show.bind(this)), this.addEventHandler(
703
- this.element,
704
- "keyup",
705
- this.elementChanged.bind(this)
706
- ), this.addEventHandler(
707
- this.element,
708
- "keydown",
709
- this.keydown.bind(this)
710
- )) : this.addEventHandler(this.element, "click", this.toggle.bind(this)), this.addEventHandler(
711
- this.container,
712
- "click",
713
- this.containerClick.bind(this)
714
- ), this.addEventHandler(
715
- this.container,
716
- "mouseover",
717
- this.containerMouseOver.bind(this)
718
- ), this.addEventHandler(
719
- this.container,
720
- "mouseleave",
721
- this.containerMouseLeave.bind(this)
722
- ), this.addEventHandler(
723
- this.container,
724
- "change",
725
- this.containerChange.bind(this)
726
- ), setTimeout(() => {
727
- this.container.querySelectorAll(
728
- "select.monthselect, select.yearselect"
729
- ).forEach((e) => {
730
- this.addEventHandler(
731
- e,
732
- "change",
733
- this.monthOrYearChanged.bind(this)
734
- );
735
- });
736
- }, 100);
679
+ positionForDesktop() {
680
+ const t = this.element.getBoundingClientRect();
681
+ this.resetContainerPosition();
682
+ const e = this.container.offsetWidth, a = this.container.offsetHeight, { top: i, drops: s } = this.calculateVerticalPosition(
683
+ t,
684
+ a
685
+ ), r = this.calculateHorizontalPosition(
686
+ t,
687
+ e
688
+ );
689
+ this.applyDropUpClass(s), this.applyFinalPosition(i, r);
737
690
  }
738
- addEventHandler(t, e, i) {
739
- const a = `${e}_${Math.random()}`;
740
- this.boundHandlers.set(a, i), t.addEventListener(e, i);
691
+ resetContainerPosition() {
692
+ this.container.style.top = "0", this.container.style.left = "0", this.container.style.right = "auto", this.container.style.position = "fixed";
741
693
  }
742
- containerChange(t) {
743
- if (t.target.matches("select.monthselect, select.yearselect")) {
744
- this.monthOrYearChanged(t);
745
- return;
694
+ calculateVerticalPosition(t, e) {
695
+ let a, i = this.options.drops;
696
+ switch (i) {
697
+ case "auto":
698
+ a = t.bottom + 5, a + e >= window.innerHeight && (a = t.top - e - 5, i = "up");
699
+ break;
700
+ case "up":
701
+ a = t.top - e - 5;
702
+ break;
703
+ default:
704
+ a = t.bottom + 5;
705
+ break;
746
706
  }
707
+ return { top: Math.max(9, a), drops: i };
747
708
  }
748
- containerMouseOver(t) {
749
- if (t.target.matches("td.available")) {
750
- this.hoverDate(t);
751
- return;
709
+ calculateHorizontalPosition(t, e) {
710
+ let a;
711
+ switch (this.options.opens) {
712
+ case "left":
713
+ a = t.right - e;
714
+ break;
715
+ case "center":
716
+ a = t.left + t.width / 2 - e / 2;
717
+ break;
718
+ default:
719
+ a = t.left;
720
+ break;
752
721
  }
722
+ return a < 9 ? a = 9 : a + e > window.innerWidth - 9 && (a = window.innerWidth - e - 9), a;
753
723
  }
754
- containerMouseLeave() {
755
- this.state.hoverDate && (this.state.hoverDate = null, this.updateDateClasses());
724
+ applyDropUpClass(t) {
725
+ t === "up" ? this.container.classList.add("drop-up") : this.container.classList.remove("drop-up");
756
726
  }
757
- containerClick(t) {
758
- const e = t.target;
759
- if (!(e.tagName === "SELECT" || e.closest("select"))) {
760
- if (e.matches(".ranges li")) {
761
- this.clickRange(t);
762
- return;
763
- }
764
- if (e.matches(".applyBtn")) {
765
- this.clickApply(t);
766
- return;
767
- }
768
- if (e.matches(".cancelBtn")) {
769
- this.clickCancel(t);
770
- return;
727
+ applyFinalPosition(t, e) {
728
+ this.container.style.top = `${t}px`, this.container.style.left = `${e}px`, this.container.style.right = "auto", this.container.style.zIndex = "99999";
729
+ }
730
+ }
731
+ class H {
732
+ constructor(t, e) {
733
+ this.options = t, this.locale = e;
734
+ }
735
+ buildCalendarMatrix(t) {
736
+ const e = x(t), a = $(e, this.locale.firstDay), i = [];
737
+ let s = [];
738
+ const r = new Date(a);
739
+ for (let n = 0; n < 42; n++) {
740
+ n > 0 && n % 7 === 0 && (i.push(s), s = []);
741
+ const o = new Date(r);
742
+ o.setDate(r.getDate() + n), s.push(o);
743
+ }
744
+ return s.length > 0 && i.push(s), i;
745
+ }
746
+ renderCalendarHTML(t, e, a, i, s, r) {
747
+ const n = t.month, o = n.getFullYear(), c = n.getMonth();
748
+ let d = '<table class="table-condensed">';
749
+ return d += this.renderHeader(e, c, o, s, r), d += this.renderDayHeaders(), d += this.renderCalendarBody(
750
+ t.calendar,
751
+ n,
752
+ a,
753
+ i
754
+ ), d += "</table>", this.options.timePicker && (d += this.renderTimeControls(
755
+ e === "left" ? a : i || a
756
+ )), d;
757
+ }
758
+ renderTimeControls(t) {
759
+ let e = '<div class="calendar-time">';
760
+ e += '<select class="hourselect">';
761
+ const a = this.options.timePicker24Hour, i = a ? 23 : 12, s = a ? 0 : 1;
762
+ for (let n = s; n <= i; n++) {
763
+ const o = a ? n : n === 0 ? 12 : n, c = String(o).padStart(2, "0"), d = a ? t.getHours() : t.getHours() % 12 || 12;
764
+ let m = !1;
765
+ if (this.options.minDate || this.options.maxDate) {
766
+ const D = new Date(t), M = a ? o : t.getHours() >= 12 ? o === 12 ? 12 : o + 12 : o === 12 ? 0 : o;
767
+ if (D.setHours(M), this.options.minDate) {
768
+ const v = new Date(D);
769
+ v.setMinutes(59), v < this.options.minDate && (m = !0);
770
+ }
771
+ if (this.options.maxDate) {
772
+ const v = new Date(D);
773
+ v.setMinutes(0), v > this.options.maxDate && (m = !0);
774
+ }
771
775
  }
772
- if (e.matches(".prev")) {
773
- this.clickPrev(t);
774
- return;
776
+ e += `<option value="${o}"${o === d && !m ? ' selected="selected"' : ""}${m ? ' disabled="disabled" class="disabled"' : ""}>${c}</option>`;
777
+ }
778
+ e += "</select>", e += " : ", e += '<select class="minuteselect">';
779
+ const r = this.options.timePickerIncrement || 1;
780
+ for (let n = 0; n < 60; n += r) {
781
+ const o = String(n).padStart(2, "0");
782
+ let c = !1;
783
+ if (this.options.minDate || this.options.maxDate) {
784
+ const p = new Date(t);
785
+ if (p.setMinutes(n), this.options.minDate) {
786
+ const h = new Date(p);
787
+ h.setSeconds(59), h < this.options.minDate && (c = !0);
788
+ }
789
+ if (this.options.maxDate) {
790
+ const h = new Date(p);
791
+ h.setSeconds(0), h > this.options.maxDate && (c = !0);
792
+ }
775
793
  }
776
- if (e.matches(".next")) {
777
- this.clickNext(t);
778
- return;
794
+ const d = n === t.getMinutes() && !c ? ' selected="selected"' : "";
795
+ e += `<option value="${n}"${d}${c ? ' disabled="disabled" class="disabled"' : ""}>${o}</option>`;
796
+ }
797
+ if (e += "</select>", this.options.timePickerSeconds) {
798
+ e += " : ", e += '<select class="secondselect">';
799
+ for (let n = 0; n < 60; n++) {
800
+ const o = String(n).padStart(2, "0");
801
+ let c = !1;
802
+ if (this.options.minDate || this.options.maxDate) {
803
+ const p = new Date(t);
804
+ p.setSeconds(n), this.options.minDate && p < this.options.minDate && (c = !0), this.options.maxDate && p > this.options.maxDate && (c = !0);
805
+ }
806
+ const d = n === t.getSeconds() && !c ? ' selected="selected"' : "";
807
+ e += `<option value="${n}"${d}${c ? ' disabled="disabled" class="disabled"' : ""}>${o}</option>`;
779
808
  }
780
- if (e.matches("td.available")) {
781
- this.clickDate(t);
782
- return;
809
+ e += "</select>";
810
+ }
811
+ if (!a) {
812
+ e += " ", e += '<select class="ampmselect">';
813
+ const n = t.getHours() < 12;
814
+ let o = !1, c = !1;
815
+ if (this.options.minDate || this.options.maxDate) {
816
+ const p = new Date(t);
817
+ p.setHours(6, 0, 0);
818
+ const h = new Date(t);
819
+ h.setHours(18, 0, 0), this.options.minDate && p < this.options.minDate && (o = !0), this.options.maxDate && h > this.options.maxDate && (c = !0);
820
+ }
821
+ const d = o ? ' disabled="disabled" class="disabled"' : "", m = c ? ' disabled="disabled" class="disabled"' : "";
822
+ e += `<option value="AM"${n ? ' selected="selected"' : ""}${d}>AM</option>`, e += `<option value="PM"${n ? "" : ' selected="selected"'}${m}>PM</option>`, e += "</select>";
823
+ }
824
+ return e += "</div>", e;
825
+ }
826
+ renderHeader(t, e, a, i, s) {
827
+ let r = "<thead><tr>";
828
+ i && (!this.options.linkedCalendars || t === "left") ? r += '<th class="prev available"><span></span></th>' : r += "<th></th>";
829
+ let n = this.locale.monthNames[e] + " " + a;
830
+ return this.options.showDropdowns && (n = this.renderDropdowns(e, a)), r += `<th colspan="5" class="month">${n}</th>`, s && (!this.options.linkedCalendars || t === "right" || this.options.singleDatePicker) ? r += '<th class="next available"><span></span></th>' : r += "<th></th>", r += "</tr>", r;
831
+ }
832
+ renderDayHeaders() {
833
+ let t = "<tr>";
834
+ for (const e of this.locale.daysOfWeek)
835
+ t += `<th>${e}</th>`;
836
+ return t += "</tr></thead>", t;
837
+ }
838
+ renderCalendarBody(t, e, a, i) {
839
+ let s = "<tbody>";
840
+ for (const r of t) {
841
+ s += "<tr>";
842
+ for (const n of r) {
843
+ const o = this.getDayClasses(
844
+ n,
845
+ e,
846
+ a,
847
+ i
848
+ ), c = o.includes("disabled"), d = o.join(" ") + (c ? "" : " available");
849
+ s += `<td class="${d}" data-date="${C(
850
+ n,
851
+ "YYYY-MM-DD"
852
+ )}">${n.getDate()}</td>`;
783
853
  }
854
+ s += "</tr>";
784
855
  }
856
+ return s += "</tbody>", s;
785
857
  }
786
- preventBlur(t) {
787
- const e = t.target;
788
- e.tagName === "SELECT" || e.closest("select") || t.preventDefault();
858
+ renderDropdowns(t, e) {
859
+ const { minYear: a, maxYear: i } = this.calculateYearRange(e), s = this.renderMonthDropdown(
860
+ t,
861
+ e,
862
+ a,
863
+ i
864
+ ), r = this.renderYearDropdown(e, a, i);
865
+ return s + " " + r;
789
866
  }
790
- show() {
791
- this.state.isShowing || (this.state.oldStartDate = new Date(this.state.startDate), this.state.oldEndDate = this.state.endDate ? new Date(this.state.endDate) : null, this.applyTheme(), this.documentClickHandler = this.outsideClick.bind(this), this.documentFocusHandler = this.outsideFocus.bind(this), document.addEventListener("mousedown", this.documentClickHandler, !0), document.addEventListener("focusin", this.documentFocusHandler, !0), this.resizeHandler = this.move.bind(this), this.scrollHandler = this.move.bind(this), window.addEventListener("resize", this.resizeHandler), window.addEventListener("scroll", this.scrollHandler, !0), this.updateView(), this.container.style.display = "block", setTimeout(() => {
792
- this.move();
793
- }, 0), this.dispatchEvent("show.daterangepicker"), this.state.isShowing = !0);
867
+ calculateYearRange(t) {
868
+ let e = this.options.minYear, a = this.options.maxYear;
869
+ return this.options.minDate && (e = Math.max(e, this.options.minDate.getFullYear())), this.options.maxDate && (a = Math.min(a, this.options.maxDate.getFullYear())), { minYear: e, maxYear: a };
794
870
  }
795
- hide() {
796
- this.state.isShowing && (this.state.endDate || (this.state.startDate = new Date(this.state.oldStartDate), this.state.endDate = this.state.oldEndDate ? new Date(this.state.oldEndDate) : null), (!x(this.state.startDate, this.state.oldStartDate, "day") || this.state.endDate && this.state.oldEndDate && !x(this.state.endDate, this.state.oldEndDate, "day")) && this.callback(
797
- new Date(this.state.startDate),
798
- this.state.endDate ? new Date(this.state.endDate) : new Date(this.state.startDate),
799
- this.state.chosenLabel || void 0
800
- ), this.updateElement(), this.removeDocumentListeners(), this.container.style.display = "none", this.dispatchEvent("hide.daterangepicker"), this.state.isShowing = !1);
871
+ renderMonthDropdown(t, e, a, i) {
872
+ const s = e === a, r = e === i;
873
+ let n = '<select class="monthselect">';
874
+ for (let o = 0; o < 12; o++) {
875
+ let c = !1;
876
+ s && this.options.minDate && o < this.options.minDate.getMonth() && (c = !0), r && this.options.maxDate && o > this.options.maxDate.getMonth() && (c = !0), n += `<option value="${o}"${o === t ? ' selected="selected"' : ""}${c ? ' disabled="disabled"' : ""}>${this.locale.monthNames[o]}</option>`;
877
+ }
878
+ return n += "</select>", n;
801
879
  }
802
- removeDocumentListeners() {
803
- this.documentClickHandler && (document.removeEventListener(
804
- "mousedown",
805
- this.documentClickHandler,
806
- !0
807
- ), this.documentClickHandler = void 0), this.documentFocusHandler && (document.removeEventListener("focusin", this.documentFocusHandler, !0), this.documentFocusHandler = void 0), this.resizeHandler && (window.removeEventListener("resize", this.resizeHandler), this.resizeHandler = void 0), this.scrollHandler && (window.removeEventListener("scroll", this.scrollHandler, !0), this.scrollHandler = void 0);
880
+ renderYearDropdown(t, e, a) {
881
+ let i = '<select class="yearselect">';
882
+ for (let s = e; s <= a; s++)
883
+ i += `<option value="${s}"${s === t ? ' selected="selected"' : ""}>${s}</option>`;
884
+ return i += "</select>", i;
808
885
  }
809
- outsideClick(t) {
810
- const e = t.target;
811
- this.element.contains(e) || this.container.contains(e) || e.closest(".datex-picker") || e.tagName === "SELECT" || e.closest("select") || (this.hide(), this.dispatchEvent("outsideClick.daterangepicker"));
886
+ getDayClasses(t, e, a, i) {
887
+ const s = [];
888
+ return u(t, /* @__PURE__ */ new Date(), "day") && s.push("today"), (t.getDay() === 0 || t.getDay() === 6) && s.push("weekend"), t.getMonth() !== e.getMonth() && s.push("off", "ends"), this.options.minDate && g(t, w(this.options.minDate)) && s.push("off", "disabled"), this.options.maxDate && k(t, S(this.options.maxDate)) && s.push("off", "disabled"), u(t, a, "day") && s.push("active", "start-date"), i && u(t, i, "day") && s.push("active", "end-date"), i && k(t, a) && g(t, i) && s.push("in-range"), s;
812
889
  }
813
- outsideFocus(t) {
814
- const e = t.target;
815
- this.element.contains(e) || this.container.contains(e) || e.closest(".datex-picker") || setTimeout(() => {
816
- const i = document.activeElement;
817
- i && !this.element.contains(i) && !this.container.contains(i) && !i.closest(".datex-picker") && this.hide();
818
- }, 50);
890
+ canNavigatePrevious(t) {
891
+ return !this.options.minDate || k(x(t), this.options.minDate);
819
892
  }
820
- toggle() {
821
- this.state.isShowing ? this.hide() : this.show();
893
+ canNavigateNext(t) {
894
+ return !this.options.maxDate || g(L(t), this.options.maxDate);
822
895
  }
823
- updateView() {
824
- if (this.options.timePicker) {
825
- this.renderTimePicker("left"), this.renderTimePicker("right");
826
- const t = this.container.querySelectorAll(
827
- ".right .calendar-time select"
828
- );
829
- this.state.endDate ? t.forEach((e) => {
830
- e.disabled = !1, e.classList.remove("disabled");
831
- }) : t.forEach((e) => {
832
- e.disabled = !0, e.classList.add("disabled");
833
- });
834
- }
835
- this.updateMonthsInView(), this.updateCalendars(), this.updateFormInputs(), this.updateSelectedDisplay(), this.calculateChosenLabel();
896
+ }
897
+ class I {
898
+ constructor(t = {}) {
899
+ this.validation = t;
836
900
  }
837
- updateMonthsInView() {
838
- this.state.endDate ? (this.state.leftCalendar.month = this.getStartOfMonth(
839
- this.state.startDate
840
- ), !this.options.linkedCalendars && (this.state.endDate.getMonth() !== this.state.startDate.getMonth() || this.state.endDate.getFullYear() !== this.state.startDate.getFullYear()) ? this.state.rightCalendar.month = this.getStartOfMonth(
841
- this.state.endDate
842
- ) : this.state.rightCalendar.month = y(
843
- this.state.leftCalendar.month,
844
- 1
845
- )) : (this.state.leftCalendar.month = this.getStartOfMonth(
846
- this.state.startDate
847
- ), this.state.rightCalendar.month = y(
848
- this.state.leftCalendar.month,
849
- 1
850
- ));
901
+ updateValidation(t) {
902
+ this.validation = { ...this.validation, ...t };
851
903
  }
852
- getStartOfMonth(t) {
853
- return new Date(t.getFullYear(), t.getMonth(), 1);
904
+ validateDate(t) {
905
+ var e, a, i;
906
+ return (e = this.validation.disabledDates) != null && e.some((s) => this.isSameDate(s, t)) ? {
907
+ isValid: !1,
908
+ error: "Esta fecha está deshabilitada",
909
+ errorCode: "DISABLED_DATE"
910
+ } : (a = this.validation.disabledDaysOfWeek) != null && a.includes(t.getDay()) ? {
911
+ isValid: !1,
912
+ error: `Los ${[
913
+ "Domingo",
914
+ "Lunes",
915
+ "Martes",
916
+ "Miércoles",
917
+ "Jueves",
918
+ "Viernes",
919
+ "Sábado"
920
+ ][t.getDay()]}s están deshabilitados`,
921
+ errorCode: "DISABLED_DAY_OF_WEEK"
922
+ } : this.validation.businessDaysOnly && this.isWeekend(t) ? {
923
+ isValid: !1,
924
+ error: "Solo se permiten días laborables",
925
+ errorCode: "BUSINESS_DAYS_ONLY"
926
+ } : (i = this.validation.holidays) != null && i.some((s) => this.isSameDate(s, t)) ? {
927
+ isValid: !1,
928
+ error: "Los días festivos están deshabilitados",
929
+ errorCode: "HOLIDAY_DISABLED"
930
+ } : this.validation.enabledDateRanges && !this.isDateInEnabledRanges(t) ? {
931
+ isValid: !1,
932
+ error: "Esta fecha está fuera de los rangos permitidos",
933
+ errorCode: "OUTSIDE_ENABLED_RANGE"
934
+ } : this.validation.customValidator && !this.validation.customValidator(t) ? {
935
+ isValid: !1,
936
+ error: "Esta fecha no cumple con los criterios personalizados",
937
+ errorCode: "CUSTOM_VALIDATION_FAILED"
938
+ } : { isValid: !0 };
854
939
  }
855
- getEndOfMonth(t) {
856
- return new Date(t.getFullYear(), t.getMonth() + 1, 0);
940
+ validateDateRange(t, e) {
941
+ const a = this.validateDate(t);
942
+ if (!a.isValid)
943
+ return a;
944
+ const i = this.validateDate(e);
945
+ return i.isValid ? this.validation.minDaysBetween && this.getDaysBetween(t, e) < this.validation.minDaysBetween ? {
946
+ isValid: !1,
947
+ error: `Debe haber al menos ${this.validation.minDaysBetween} días entre las fechas`,
948
+ errorCode: "MIN_DAYS_BETWEEN"
949
+ } : this.validation.maxDaysBetween && this.getDaysBetween(t, e) > this.validation.maxDaysBetween ? {
950
+ isValid: !1,
951
+ error: `No puede haber más de ${this.validation.maxDaysBetween} días entre las fechas`,
952
+ errorCode: "MAX_DAYS_BETWEEN"
953
+ } : { isValid: !0 } : i;
857
954
  }
858
- getStartOfWeek(t, e = 1) {
859
- const a = (t.getDay() - e + 7) % 7, n = new Date(t);
860
- return n.setDate(t.getDate() - a), n;
955
+ // Utility methods
956
+ isSameDate(t, e) {
957
+ return t.getFullYear() === e.getFullYear() && t.getMonth() === e.getMonth() && t.getDate() === e.getDate();
861
958
  }
862
- updateCalendars() {
863
- this.renderCalendar("left"), this.options.singleDatePicker || this.renderCalendar("right"), setTimeout(() => {
864
- this.container.querySelectorAll(
865
- "select.monthselect, select.yearselect"
866
- ).forEach((e) => {
867
- e.removeEventListener(
868
- "change",
869
- this.monthOrYearChanged.bind(this)
870
- ), e.addEventListener("change", this.monthOrYearChanged.bind(this));
871
- });
872
- }, 10);
959
+ isWeekend(t) {
960
+ const e = t.getDay();
961
+ return e === 0 || e === 6;
873
962
  }
874
- renderCalendar(t) {
875
- const e = t === "left" ? this.state.leftCalendar : this.state.rightCalendar, i = this.container.querySelector(
876
- `.drp-calendar.${t} .calendar-table`
877
- ), a = e.month, n = a.getFullYear(), o = a.getMonth(), r = this.getStartOfMonth(a), f = this.getStartOfWeek(r, this.locale.firstDay), h = [];
878
- let d = [];
879
- const p = new Date(f);
880
- for (let D = 0; D < 42; D++) {
881
- D > 0 && D % 7 === 0 && (h.push(d), d = []);
882
- const k = new Date(p);
883
- k.setDate(p.getDate() + D), d.push(k);
884
- }
885
- d.length > 0 && h.push(d), e.calendar = h;
886
- let s = '<table class="table-condensed">';
887
- s += "<thead>", s += "<tr>";
888
- const l = !this.options.minDate || b(this.getStartOfMonth(a), this.options.minDate), m = !this.options.maxDate || g(this.getEndOfMonth(a), this.options.maxDate);
889
- l && (!this.options.linkedCalendars || t === "left") ? s += '<th class="prev available"><span></span></th>' : s += "<th></th>";
890
- let u = this.locale.monthNames[o] + " " + n;
891
- this.options.showDropdowns && (u = this.renderDropdowns(o, n, t)), s += `<th colspan="5" class="month">${u}</th>`, m && (!this.options.linkedCalendars || t === "right" || this.options.singleDatePicker) ? s += '<th class="next available"><span></span></th>' : s += "<th></th>", s += "</tr>", s += "<tr>";
892
- for (const D of this.locale.daysOfWeek)
893
- s += `<th>${D}</th>`;
894
- s += "</tr>", s += "</thead>", s += "<tbody>";
895
- for (const D of h) {
896
- s += "<tr>";
897
- for (const k of D) {
898
- const w = this.getDayClasses(k, a), H = w.includes("disabled"), P = w.join(" ") + (H ? "" : " available");
899
- s += `<td class="${P}" data-date="${v(
900
- k,
901
- "YYYY-MM-DD"
902
- )}">${k.getDate()}</td>`;
903
- }
904
- s += "</tr>";
963
+ getDaysBetween(t, e) {
964
+ const a = e.getTime() - t.getTime();
965
+ return Math.ceil(a / (1e3 * 3600 * 24));
966
+ }
967
+ isDateInEnabledRanges(t) {
968
+ return this.validation.enabledDateRanges ? this.validation.enabledDateRanges.some(([e, a]) => t >= e && t <= a) : !0;
969
+ }
970
+ // Public utility methods
971
+ getBusinessDays(t, e) {
972
+ let a = 0;
973
+ const i = new Date(t);
974
+ for (; i <= e; )
975
+ this.isWeekend(i) || a++, i.setDate(i.getDate() + 1);
976
+ return a;
977
+ }
978
+ addBusinessDays(t, e) {
979
+ const a = new Date(t);
980
+ let i = 0;
981
+ for (; i < e; )
982
+ a.setDate(a.getDate() + 1), this.isWeekend(a) || i++;
983
+ return a;
984
+ }
985
+ isHoliday(t) {
986
+ var e;
987
+ return ((e = this.validation.holidays) == null ? void 0 : e.some((a) => this.isSameDate(a, t))) || !1;
988
+ }
989
+ }
990
+ class P {
991
+ constructor(t, e = {}) {
992
+ this.currentFocusedDate = null, this.isActive = !1, this.container = t, this.options = {
993
+ enabled: !0,
994
+ shortcuts: {
995
+ today: "t",
996
+ clear: "c",
997
+ close: "Escape",
998
+ apply: "Enter",
999
+ cancel: "Escape",
1000
+ ...e.shortcuts
1001
+ },
1002
+ ...e
1003
+ }, this.options.enabled && this.setupKeyboardEvents();
1004
+ }
1005
+ setHandlers(t) {
1006
+ this.onDateSelect = t.onDateSelect, this.onClose = t.onClose, this.onApply = t.onApply, this.onToday = t.onToday, this.onClear = t.onClear;
1007
+ }
1008
+ activate(t) {
1009
+ this.isActive = !0, this.currentFocusedDate = t ? new Date(t.getTime()) : /* @__PURE__ */ new Date(), setTimeout(() => {
1010
+ this.isActive && this.updateFocusedDate();
1011
+ }, 100), this.container.focus({ preventScroll: !0 });
1012
+ }
1013
+ deactivate() {
1014
+ this.isActive = !1, this.currentFocusedDate = null, this.removeFocusStyles();
1015
+ }
1016
+ setupKeyboardEvents() {
1017
+ this.container.setAttribute("tabindex", "0"), this.container.addEventListener("keydown", this.handleKeyDown.bind(this)), this.container.addEventListener("focus", this.handleFocus.bind(this)), this.container.addEventListener("blur", this.handleBlur.bind(this));
1018
+ }
1019
+ handleKeyDown(t) {
1020
+ var r, n, o, c;
1021
+ if (!this.isActive || !this.currentFocusedDate) return;
1022
+ const { key: e, ctrlKey: a, shiftKey: i, altKey: s } = t;
1023
+ switch (e) {
1024
+ case "ArrowLeft":
1025
+ t.preventDefault(), this.navigateDate(-1);
1026
+ break;
1027
+ case "ArrowRight":
1028
+ t.preventDefault(), this.navigateDate(1);
1029
+ break;
1030
+ case "ArrowUp":
1031
+ t.preventDefault(), this.navigateDate(-7);
1032
+ break;
1033
+ case "ArrowDown":
1034
+ t.preventDefault(), this.navigateDate(7);
1035
+ break;
1036
+ case "Home":
1037
+ t.preventDefault(), this.navigateToStartOfWeek();
1038
+ break;
1039
+ case "End":
1040
+ t.preventDefault(), this.navigateToEndOfWeek();
1041
+ break;
1042
+ case "PageUp":
1043
+ t.preventDefault(), this.navigateMonth(i ? -12 : -1);
1044
+ break;
1045
+ case "PageDown":
1046
+ t.preventDefault(), this.navigateMonth(i ? 12 : 1);
1047
+ break;
905
1048
  }
906
- s += "</tbody>", s += "</table>", i.innerHTML = s, this.options.timePicker && this.renderTimePicker(t);
907
- }
908
- renderDropdowns(t, e, i) {
909
- let a = this.options.minYear, n = this.options.maxYear;
910
- this.options.minDate && (a = Math.max(a, this.options.minDate.getFullYear())), this.options.maxDate && (n = Math.min(n, this.options.maxDate.getFullYear()));
911
- const o = e, r = o === a, f = o === n;
912
- let h = '<select class="monthselect">';
913
- for (let p = 0; p < 12; p++) {
914
- let s = !1;
915
- r && this.options.minDate && p < this.options.minDate.getMonth() && (s = !0), f && this.options.maxDate && p > this.options.maxDate.getMonth() && (s = !0), h += `<option value="${p}"${p === t ? ' selected="selected"' : ""}${s ? ' disabled="disabled"' : ""}>${this.locale.monthNames[p]}</option>`;
1049
+ switch (e) {
1050
+ case "Enter":
1051
+ case " ":
1052
+ if (t.preventDefault(), this.currentFocusedDate && this.onDateSelect) {
1053
+ const d = new Date(this.currentFocusedDate.getTime());
1054
+ console.log("=== KEYBOARD DEBUG ==="), console.log("Original focused date:", this.currentFocusedDate), console.log(
1055
+ "Original focused day:",
1056
+ this.currentFocusedDate.getDate()
1057
+ ), console.log("Copy to select:", d), console.log("Copy day:", d.getDate()), console.log(
1058
+ "Are they equal?",
1059
+ this.currentFocusedDate.getTime() === d.getTime()
1060
+ ), console.log("======================"), this.onDateSelect(d);
1061
+ }
1062
+ break;
1063
+ case "Escape":
1064
+ t.preventDefault(), this.onClose && this.onClose();
1065
+ break;
916
1066
  }
917
- h += "</select>";
918
- let d = '<select class="yearselect">';
919
- for (let p = a; p <= n; p++)
920
- d += `<option value="${p}"${p === e ? ' selected="selected"' : ""}>${p}</option>`;
921
- return d += "</select>", h + " " + d;
1067
+ if (!a && !s)
1068
+ switch (e.toLowerCase()) {
1069
+ case ((n = (r = this.options.shortcuts) == null ? void 0 : r.today) == null ? void 0 : n.toLowerCase()):
1070
+ t.preventDefault(), this.onToday && this.onToday();
1071
+ break;
1072
+ case ((c = (o = this.options.shortcuts) == null ? void 0 : o.clear) == null ? void 0 : c.toLowerCase()):
1073
+ t.preventDefault(), this.onClear && this.onClear();
1074
+ break;
1075
+ }
1076
+ if (a && !s && !i)
1077
+ switch (e.toLowerCase()) {
1078
+ case "enter":
1079
+ t.preventDefault(), this.onApply && this.onApply();
1080
+ break;
1081
+ }
922
1082
  }
923
- getDayClasses(t, e) {
924
- const i = [];
925
- return x(t, /* @__PURE__ */ new Date(), "day") && i.push("today"), (t.getDay() === 0 || t.getDay() === 6) && i.push("weekend"), t.getMonth() !== e.getMonth() && i.push("off", "ends"), this.options.minDate && g(t, M(this.options.minDate)) && i.push("off", "disabled"), this.options.maxDate && b(t, E(this.options.maxDate)) && i.push("off", "disabled"), x(t, this.state.startDate, "day") && i.push("active", "start-date"), this.state.endDate && x(t, this.state.endDate, "day") && i.push("active", "end-date"), this.state.endDate && b(t, this.state.startDate) && g(t, this.state.endDate) && i.push("in-range"), i;
1083
+ handleFocus() {
1084
+ this.isActive || (this.isActive = !0, this.currentFocusedDate = this.currentFocusedDate || /* @__PURE__ */ new Date(), setTimeout(() => {
1085
+ this.isActive && this.updateFocusedDate();
1086
+ }, 150));
926
1087
  }
927
- updateFormInputs() {
928
- const t = this.container.querySelector(
929
- ".applyBtn"
930
- ), e = this.options.singleDatePicker || this.state.endDate && (g(this.state.startDate, this.state.endDate) || x(this.state.startDate, this.state.endDate, "day"));
931
- t.disabled = !e;
1088
+ handleBlur() {
1089
+ setTimeout(() => {
1090
+ this.container.contains(document.activeElement) || this.deactivate();
1091
+ }, 100);
932
1092
  }
933
- updateSelectedDisplay() {
934
- const t = this.container.querySelector(".drp-selected");
935
- let e = v(this.state.startDate, this.locale.format);
936
- !this.options.singleDatePicker && this.state.endDate && (e += this.locale.separator + v(this.state.endDate, this.locale.format)), t.textContent = e;
1093
+ navigateDate(t) {
1094
+ if (!this.currentFocusedDate) return;
1095
+ const e = new Date(this.currentFocusedDate.getTime());
1096
+ e.setDate(e.getDate() + t), this.currentFocusedDate = e, this.updateFocusedDate();
937
1097
  }
938
- renderTimePicker(t) {
939
- if (t === "right" && !this.state.endDate) return;
1098
+ navigateMonth(t) {
1099
+ if (!this.currentFocusedDate) return;
1100
+ const e = new Date(this.currentFocusedDate.getTime());
1101
+ e.setMonth(e.getMonth() + t), this.currentFocusedDate = e, this.updateFocusedDate();
1102
+ }
1103
+ navigateToStartOfWeek() {
1104
+ if (!this.currentFocusedDate) return;
1105
+ const t = new Date(this.currentFocusedDate.getTime()), e = t.getDay();
1106
+ t.setDate(t.getDate() - e), this.currentFocusedDate = t, this.updateFocusedDate();
1107
+ }
1108
+ navigateToEndOfWeek() {
1109
+ if (!this.currentFocusedDate) return;
1110
+ const t = new Date(this.currentFocusedDate.getTime()), e = t.getDay();
1111
+ t.setDate(t.getDate() + (6 - e)), this.currentFocusedDate = t, this.updateFocusedDate();
1112
+ }
1113
+ updateFocusedDate() {
1114
+ if (!this.currentFocusedDate) return;
1115
+ this.removeFocusStyles();
1116
+ const t = this.formatDateForSelector(this.currentFocusedDate);
1117
+ console.log("Keyboard: Looking for cell with data-date:", t), console.log(
1118
+ "Keyboard: Current focused date:",
1119
+ this.currentFocusedDate.toDateString()
1120
+ );
940
1121
  const e = this.container.querySelector(
941
- `.drp-calendar.${t}`
1122
+ `[data-date="${t}"]`
942
1123
  );
943
- if (!e.querySelector(".calendar-time")) {
944
- const s = document.createElement("div");
945
- s.className = "calendar-time", e.appendChild(s);
946
- }
947
- let a, n = null, o = this.options.maxDate;
948
- if (this.options.maxSpan && (!this.options.maxDate || b(
949
- $(this.state.startDate, this.options.maxSpan.days || 0),
950
- this.options.maxDate
951
- )) && (o = $(this.state.startDate, this.options.maxSpan.days || 0)), t === "left")
952
- a = new Date(this.state.startDate), n = this.options.minDate;
953
- else {
954
- a = this.state.endDate ? new Date(this.state.endDate) : new Date(this.state.startDate), n = this.state.startDate;
955
- const s = this.container.querySelector(
956
- ".drp-calendar.right .calendar-time"
957
- );
958
- if (s && s.innerHTML !== "") {
959
- const l = s.querySelector(
960
- ".hourselect"
961
- ), m = s.querySelector(
962
- ".minuteselect"
963
- ), u = s.querySelector(
964
- ".secondselect"
965
- ), D = s.querySelector(
966
- ".ampmselect"
967
- );
968
- if (l && l.value) {
969
- let k = parseInt(l.value, 10);
970
- if (!this.options.timePicker24Hour && D) {
971
- const w = D.value;
972
- w === "PM" && k < 12 && (k += 12), w === "AM" && k === 12 && (k = 0);
973
- }
974
- a.setHours(k);
975
- }
976
- m && m.value && a.setMinutes(parseInt(m.value, 10)), u && u.value && a.setSeconds(parseInt(u.value, 10));
1124
+ if (e) {
1125
+ if (console.log("Keyboard: Found cell, text content:", e.textContent), e.classList.add("keyboard-focused"), e.setAttribute("aria-selected", "true"), this.isActive && this.container.offsetParent !== null) {
1126
+ const a = this.container.getBoundingClientRect(), i = e.getBoundingClientRect();
1127
+ (i.top < a.top || i.bottom > a.bottom || i.left < a.left || i.right > a.right) && e.scrollIntoView({
1128
+ block: "nearest",
1129
+ inline: "nearest",
1130
+ behavior: "smooth"
1131
+ });
1132
+ }
1133
+ } else
1134
+ console.log("Keyboard: Cell not found for date:", t);
1135
+ this.addFocusStyles();
1136
+ }
1137
+ removeFocusStyles() {
1138
+ this.container.querySelectorAll(".keyboard-focused").forEach((e) => {
1139
+ e.classList.remove("keyboard-focused"), e.removeAttribute("aria-selected");
1140
+ });
1141
+ }
1142
+ addFocusStyles() {
1143
+ if (this.container.querySelector(".keyboard-focus-styles")) return;
1144
+ const t = document.createElement("style");
1145
+ t.className = "keyboard-focus-styles", t.textContent = `
1146
+ .datex-picker .calendar-table td.keyboard-focused {
1147
+ outline: 2px solid #10b981 !important;
1148
+ outline-offset: -2px !important;
1149
+ z-index: 10 !important;
1150
+ position: relative !important;
1151
+ box-shadow: 0 0 0 2px rgba(16, 185, 129, 0.2) !important;
977
1152
  }
978
- g(a, this.state.startDate) && (a = new Date(this.state.startDate)), o && b(a, o) && (a = new Date(o));
979
- }
980
- let r = '<select class="hourselect">';
981
- const f = this.options.timePicker24Hour ? 0 : 1, h = this.options.timePicker24Hour ? 23 : 12;
982
- for (let s = f; s <= h; s++) {
983
- let l = s;
984
- this.options.timePicker24Hour || (l = a.getHours() >= 12 ? s === 12 ? 12 : s + 12 : s === 12 ? 0 : s);
985
- const m = new Date(a);
986
- m.setHours(l), m.setMinutes(59);
987
- let u = !1;
988
- n && g(m, n) && (u = !0), m.setMinutes(0), o && b(m, o) && (u = !0), l === a.getHours() && !u ? r += `<option value="${s}" selected="selected">${s}</option>` : u ? r += `<option value="${s}" disabled="disabled" class="disabled">${s}</option>` : r += `<option value="${s}">${s}</option>`;
989
- }
990
- r += "</select> ", r += ': <select class="minuteselect">';
991
- for (let s = 0; s < 60; s += this.options.timePickerIncrement) {
992
- const l = s < 10 ? "0" + s : s.toString(), m = new Date(a);
993
- m.setMinutes(s), m.setSeconds(59);
994
- let u = !1;
995
- n && g(m, n) && (u = !0), m.setSeconds(0), o && b(m, o) && (u = !0), a.getMinutes() === s && !u ? r += `<option value="${s}" selected="selected">${l}</option>` : u ? r += `<option value="${s}" disabled="disabled" class="disabled">${l}</option>` : r += `<option value="${s}">${l}</option>`;
996
- }
997
- if (r += "</select> ", this.options.timePickerSeconds) {
998
- r += ': <select class="secondselect">';
999
- for (let s = 0; s < 60; s++) {
1000
- const l = s < 10 ? "0" + s : s.toString(), m = new Date(a);
1001
- m.setSeconds(s);
1002
- let u = !1;
1003
- n && g(m, n) && (u = !0), o && b(m, o) && (u = !0), a.getSeconds() === s && !u ? r += `<option value="${s}" selected="selected">${l}</option>` : u ? r += `<option value="${s}" disabled="disabled" class="disabled">${l}</option>` : r += `<option value="${s}">${l}</option>`;
1004
- }
1005
- r += "</select> ";
1006
- }
1007
- if (!this.options.timePicker24Hour) {
1008
- r += '<select class="ampmselect">';
1009
- const s = new Date(a);
1010
- s.setHours(12, 0, 0);
1011
- const l = new Date(a);
1012
- l.setHours(0, 0, 0);
1013
- let m = "", u = "";
1014
- n && g(s, n) && (m = ' disabled="disabled" class="disabled"'), o && b(l, o) && (u = ' disabled="disabled" class="disabled"'), a.getHours() >= 12 ? r += `<option value="AM"${m}>AM</option><option value="PM" selected="selected"${u}>PM</option>` : r += `<option value="AM" selected="selected"${m}>AM</option><option value="PM"${u}>PM</option>`, r += "</select>";
1153
+
1154
+ .datex-picker .calendar-table td.keyboard-focused > * {
1155
+ background: #10b981 !important;
1156
+ color: white !important;
1157
+ font-weight: 600 !important;
1158
+ }
1159
+
1160
+ /* Prevent layout shifts */
1161
+ .datex-picker {
1162
+ contain: layout style !important;
1163
+ }
1164
+
1165
+ .datex-picker .calendar-table {
1166
+ contain: layout !important;
1167
+ }
1168
+ `, document.head.appendChild(t);
1169
+ }
1170
+ formatDateForSelector(t) {
1171
+ const e = t.getFullYear(), a = String(t.getMonth() + 1).padStart(2, "0"), i = String(t.getDate()).padStart(2, "0"), s = `${e}-${a}-${i}`;
1172
+ return console.log(
1173
+ "Keyboard: Formatting date for selector:",
1174
+ t.toDateString(),
1175
+ "-> formatted:",
1176
+ s
1177
+ ), s;
1178
+ }
1179
+ // Public methods
1180
+ getCurrentFocusedDate() {
1181
+ return this.currentFocusedDate ? new Date(this.currentFocusedDate.getTime()) : null;
1182
+ }
1183
+ setFocusedDate(t) {
1184
+ this.currentFocusedDate = new Date(t.getTime()), this.updateFocusedDate();
1185
+ }
1186
+ cleanup() {
1187
+ this.container.removeEventListener(
1188
+ "keydown",
1189
+ this.handleKeyDown.bind(this)
1190
+ ), this.container.removeEventListener("focus", this.handleFocus.bind(this)), this.container.removeEventListener("blur", this.handleBlur.bind(this)), this.removeFocusStyles();
1191
+ const t = document.querySelector(".keyboard-focus-styles");
1192
+ t && t.remove();
1193
+ }
1194
+ }
1195
+ const Y = {
1196
+ format: "DD/MM/YYYY",
1197
+ separator: " - ",
1198
+ applyLabel: "Aplicar",
1199
+ cancelLabel: "Cancelar",
1200
+ customRangeLabel: "Rango Personalizado",
1201
+ daysOfWeek: ["Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"],
1202
+ monthNames: [
1203
+ "Enero",
1204
+ "Febrero",
1205
+ "Marzo",
1206
+ "Abril",
1207
+ "Mayo",
1208
+ "Junio",
1209
+ "Julio",
1210
+ "Agosto",
1211
+ "Septiembre",
1212
+ "Octubre",
1213
+ "Noviembre",
1214
+ "Diciembre"
1215
+ ],
1216
+ firstDay: 1
1217
+ }, V = {
1218
+ format: "DD/MM/YYYY HH:mm",
1219
+ separator: " - ",
1220
+ applyLabel: "Aplicar",
1221
+ cancelLabel: "Cancelar",
1222
+ customRangeLabel: "Rango Personalizado",
1223
+ daysOfWeek: ["Lu", "Ma", "Mi", "Ju", "Vi", "Sa", "Do"],
1224
+ monthNames: [
1225
+ "Enero",
1226
+ "Febrero",
1227
+ "Marzo",
1228
+ "Abril",
1229
+ "Mayo",
1230
+ "Junio",
1231
+ "Julio",
1232
+ "Agosto",
1233
+ "Septiembre",
1234
+ "Octubre",
1235
+ "Noviembre",
1236
+ "Diciembre"
1237
+ ],
1238
+ firstDay: 1
1239
+ };
1240
+ class O {
1241
+ constructor(t, e = {}, a) {
1242
+ this.element = this.resolveElement(t), this.options = this.mergeWithDefaults(e), this.locale = this.options.locale, this.callback = a || (() => {
1243
+ }), this.eventService = new A(), this.initializeState(), this.initializeServices(), this.createContainer(), this.setupEventListeners(), this.updateElement(), this.calculateChosenLabel();
1244
+ }
1245
+ resolveElement(t) {
1246
+ if (typeof t == "string") {
1247
+ const e = t.startsWith("#") ? document.getElementById(t.slice(1)) : document.querySelector(t) || document.getElementById(t);
1248
+ if (!e || !(e instanceof HTMLElement))
1249
+ throw new Error("Datex: Element not found");
1250
+ return e;
1015
1251
  }
1016
- const d = e.querySelector(".calendar-time");
1017
- d.innerHTML = r, d.querySelectorAll("select").forEach((s) => {
1018
- s.addEventListener("change", this.timeChanged.bind(this));
1252
+ return t;
1253
+ }
1254
+ mergeWithDefaults(t) {
1255
+ const e = /* @__PURE__ */ new Date(), a = {
1256
+ startDate: t.startDate || e,
1257
+ endDate: t.endDate || e,
1258
+ minDate: t.minDate ?? null,
1259
+ maxDate: t.maxDate ?? null,
1260
+ minYear: t.minYear ?? e.getFullYear() - 100,
1261
+ maxYear: t.maxYear ?? e.getFullYear() + 100,
1262
+ maxSpan: t.maxSpan ?? null,
1263
+ autoApply: t.autoApply ?? !1,
1264
+ singleDatePicker: t.singleDatePicker ?? !1,
1265
+ showDropdowns: t.showDropdowns ?? !0,
1266
+ linkedCalendars: t.linkedCalendars ?? !0,
1267
+ autoUpdateInput: t.autoUpdateInput ?? !0,
1268
+ alwaysShowCalendars: t.alwaysShowCalendars ?? !1,
1269
+ showCustomRangeLabel: t.showCustomRangeLabel ?? !0,
1270
+ timePicker: t.timePicker ?? !1,
1271
+ timePicker24Hour: t.timePicker24Hour ?? !0,
1272
+ timePickerIncrement: t.timePickerIncrement ?? 1,
1273
+ timePickerSeconds: t.timePickerSeconds ?? !1,
1274
+ ranges: t.ranges || {},
1275
+ opens: t.opens || "center",
1276
+ drops: t.drops || "auto",
1277
+ locale: t.locale || Y,
1278
+ buttonClasses: t.buttonClasses || "btn btn-sm",
1279
+ applyButtonClasses: t.applyButtonClasses || "btn-success",
1280
+ cancelButtonClasses: t.cancelButtonClasses || "btn-danger",
1281
+ theme: t.theme || E,
1282
+ validation: t.validation || {},
1283
+ events: t.events || {}
1284
+ };
1285
+ return a.timePicker && a.autoApply && (a.autoApply = !1), a;
1286
+ }
1287
+ initializeState() {
1288
+ const t = /* @__PURE__ */ new Date();
1289
+ this.state = {
1290
+ startDate: this.options.timePicker ? this.options.startDate : w(this.options.startDate),
1291
+ endDate: this.options.timePicker ? this.options.endDate : S(this.options.endDate),
1292
+ oldStartDate: this.options.timePicker ? this.options.startDate : w(this.options.startDate),
1293
+ oldEndDate: this.options.timePicker ? this.options.endDate : S(this.options.endDate),
1294
+ isShowing: !1,
1295
+ leftCalendar: { month: t, calendar: [] },
1296
+ rightCalendar: { month: f(t, 1), calendar: [] },
1297
+ chosenLabel: null,
1298
+ hoverDate: null
1299
+ };
1300
+ }
1301
+ initializeServices() {
1302
+ this.calendarService = new H(this.options, this.locale);
1303
+ }
1304
+ createContainer() {
1305
+ const t = this.buildContainerTemplate(), e = document.createElement("div");
1306
+ e.innerHTML = t.trim(), this.container = e.firstElementChild, document.body.appendChild(this.container), this.initializeContainerServices(), this.setupContainerClasses(), this.setupInitialVisibility();
1307
+ }
1308
+ buildContainerTemplate() {
1309
+ return `
1310
+ <div class="datex-picker">
1311
+ <div class="ranges"></div>
1312
+ <div class="drp-calendar left">
1313
+ <div class="calendar-table"></div>
1314
+ <div class="calendar-time"></div>
1315
+ </div>
1316
+ <div class="drp-calendar right">
1317
+ <div class="calendar-table"></div>
1318
+ <div class="calendar-time"></div>
1319
+ </div>
1320
+ <div class="drp-buttons">
1321
+ <span class="drp-selected"></span>
1322
+ <button class="cancelBtn ${this.options.buttonClasses} ${this.options.cancelButtonClasses}" type="button">
1323
+ ${this.locale.cancelLabel}
1324
+ </button>
1325
+ <button class="applyBtn ${this.options.buttonClasses} ${this.options.applyButtonClasses}" type="button">
1326
+ ${this.locale.applyLabel}
1327
+ </button>
1328
+ </div>
1329
+ </div>
1330
+ `;
1331
+ }
1332
+ initializeContainerServices() {
1333
+ this.themeService = new T(this.container, this.options.theme), this.positionService = new F(
1334
+ this.element,
1335
+ this.container,
1336
+ this.options
1337
+ ), this.validationService = new I(this.options.validation), this.keyboardService = new P(this.container, {
1338
+ enabled: !0
1339
+ }), this.keyboardService.setHandlers({
1340
+ onDateSelect: (t) => {
1341
+ this.handleKeyboardDateSelect(t);
1342
+ },
1343
+ onClose: () => {
1344
+ this.hide();
1345
+ },
1346
+ onToday: () => {
1347
+ const t = /* @__PURE__ */ new Date();
1348
+ this.setStartDate(t), this.setEndDate(t), this.updateView();
1349
+ },
1350
+ onClear: () => {
1351
+ this.clearSelection();
1352
+ }
1019
1353
  });
1020
1354
  }
1021
- timeChanged(t) {
1022
- const i = t.target.closest(".drp-calendar");
1023
- if (!i) return;
1024
- const a = i.classList.contains("left"), n = i, o = n.querySelector(".hourselect"), r = n.querySelector(
1025
- ".minuteselect"
1026
- ), f = n.querySelector(
1027
- ".secondselect"
1028
- ), h = n.querySelector(".ampmselect");
1029
- let d = parseInt(o.value, 10), p = parseInt(r.value, 10);
1030
- if (isNaN(p)) {
1031
- const l = r.options[r.options.length - 1];
1032
- p = parseInt(l.value, 10);
1033
- }
1034
- const s = this.options.timePickerSeconds && f ? parseInt(f.value, 10) : 0;
1035
- if (!this.options.timePicker24Hour && h) {
1036
- const l = h.value;
1037
- l === "PM" && d < 12 && (d += 12), l === "AM" && d === 12 && (d = 0);
1038
- }
1039
- if (a) {
1040
- const l = new Date(this.state.startDate);
1041
- l.setHours(d, p, s), this.setStartDate(l), this.options.singleDatePicker ? this.state.endDate = new Date(l) : this.state.endDate && v(this.state.endDate, "YYYY-MM-DD") === v(l, "YYYY-MM-DD") && g(this.state.endDate, l) && this.setEndDate(new Date(l));
1042
- } else if (this.state.endDate) {
1043
- const l = new Date(this.state.endDate);
1044
- l.setHours(d, p, s), this.setEndDate(l);
1045
- }
1046
- this.updateCalendars(), this.updateFormInputs(), this.renderTimePicker("left"), this.renderTimePicker("right");
1355
+ setupContainerClasses() {
1356
+ this.container.classList.add(`opens${this.options.opens}`), this.options.singleDatePicker && this.container.classList.add("single"), this.options.autoApply && this.container.classList.add("auto-apply"), Object.keys(this.options.ranges).length > 0 && (this.container.classList.add("show-ranges"), this.renderRanges()), (this.options.alwaysShowCalendars || Object.keys(this.options.ranges).length === 0) && this.container.classList.add("show-calendar"), this.options.autoApply || this.container.classList.add("show-calendar");
1047
1357
  }
1048
- updateElement() {
1049
- if (this.element.tagName === "INPUT" && this.options.autoUpdateInput) {
1050
- const t = this.element;
1051
- let e = v(this.state.startDate, this.locale.format);
1052
- !this.options.singleDatePicker && this.state.endDate && (e += this.locale.separator + v(this.state.endDate, this.locale.format)), e !== t.value && (t.value = e, this.dispatchEvent("change"));
1053
- }
1358
+ setupInitialVisibility() {
1359
+ this.options.timePicker || this.container.querySelectorAll(".calendar-time").forEach((e) => {
1360
+ e.style.display = "none";
1361
+ }), this.container.style.display = "none";
1054
1362
  }
1055
- move() {
1056
- if (!this.state.isShowing || !this.container) return;
1057
- const t = this.element.getBoundingClientRect();
1058
- let e, i = this.options.drops;
1059
- this.container.style.top = "0", this.container.style.left = "0", this.container.style.right = "auto", this.container.style.position = "fixed";
1060
- const a = this.container.offsetWidth, n = this.container.offsetHeight;
1061
- switch (i) {
1062
- case "auto":
1063
- e = t.bottom + 5, e + n >= window.innerHeight && (e = t.top - n - 5, i = "up");
1064
- break;
1065
- case "up":
1066
- e = t.top - n - 5;
1067
- break;
1068
- default:
1069
- e = t.bottom + 5;
1070
- break;
1363
+ // Public API methods
1364
+ show() {
1365
+ this.state.isShowing || (this.storeOldValues(), this.themeService.applyTheme(), this.setupDocumentListeners(), this.updateView(), this.displayContainer(), this.positionContainer(), setTimeout(() => {
1366
+ this.state.isShowing && this.keyboardService.activate(this.state.startDate);
1367
+ }, 200), this.dispatchShowEvent());
1368
+ }
1369
+ hide() {
1370
+ this.state.isShowing && (this.revertIfIncomplete(), this.triggerCallbackIfChanged(), this.updateElement(), this.removeDocumentListeners(), this.keyboardService.deactivate(), this.hideContainer(), this.dispatchHideEvent());
1371
+ }
1372
+ toggle() {
1373
+ this.state.isShowing ? this.hide() : this.show();
1374
+ }
1375
+ setStartDate(t) {
1376
+ this.state.startDate = this.options.timePicker ? new Date(t) : w(t), this.options.timePickerIncrement && this.options.timePicker && this.roundToIncrement(this.state.startDate), this.updateView();
1377
+ }
1378
+ setEndDate(t) {
1379
+ this.state.endDate = this.options.timePicker ? new Date(t) : S(t), this.options.timePickerIncrement && this.options.timePicker && this.roundToIncrement(this.state.endDate), this.updateView();
1380
+ }
1381
+ getStartDate() {
1382
+ return new Date(this.state.startDate);
1383
+ }
1384
+ getEndDate() {
1385
+ return this.state.endDate ? new Date(this.state.endDate) : null;
1386
+ }
1387
+ setTheme(t) {
1388
+ this.themeService.setTheme(t);
1389
+ }
1390
+ setThemeMode(t) {
1391
+ this.themeService.setMode(t);
1392
+ }
1393
+ getThemeMode() {
1394
+ return this.themeService.getMode();
1395
+ }
1396
+ getCurrentThemeMode() {
1397
+ return this.themeService.getCurrentMode();
1398
+ }
1399
+ // Validation methods
1400
+ updateValidation(t) {
1401
+ this.validationService.updateValidation(t);
1402
+ }
1403
+ validateDate(t) {
1404
+ return this.validationService.validateDate(t);
1405
+ }
1406
+ validateDateRange(t, e) {
1407
+ return this.validationService.validateDateRange(t, e);
1408
+ }
1409
+ // Keyboard navigation methods
1410
+ enableKeyboardNavigation() {
1411
+ this.state.isShowing && this.keyboardService.activate(this.state.startDate);
1412
+ }
1413
+ disableKeyboardNavigation() {
1414
+ this.keyboardService.deactivate();
1415
+ }
1416
+ setKeyboardFocusedDate(t) {
1417
+ this.keyboardService.setFocusedDate(t);
1418
+ }
1419
+ remove() {
1420
+ this.cleanup();
1421
+ }
1422
+ // Private helper methods
1423
+ storeOldValues() {
1424
+ this.state.oldStartDate = new Date(this.state.startDate), this.state.oldEndDate = this.state.endDate ? new Date(this.state.endDate) : null;
1425
+ }
1426
+ setupDocumentListeners() {
1427
+ this.eventService.setDocumentListeners(
1428
+ this.handleOutsideClick.bind(this),
1429
+ this.handleOutsideFocus.bind(this)
1430
+ ), this.eventService.setWindowListeners(
1431
+ this.positionContainer.bind(this),
1432
+ this.positionContainer.bind(this)
1433
+ );
1434
+ }
1435
+ removeDocumentListeners() {
1436
+ this.eventService.removeDocumentListeners(), this.eventService.removeWindowListeners();
1437
+ }
1438
+ displayContainer() {
1439
+ this.container.style.display = "block", this.state.isShowing = !0;
1440
+ }
1441
+ hideContainer() {
1442
+ this.container.style.display = "none", this.state.isShowing = !1;
1443
+ }
1444
+ positionContainer() {
1445
+ setTimeout(() => this.positionService.calculatePosition(), 0);
1446
+ }
1447
+ revertIfIncomplete() {
1448
+ this.state.endDate || (this.state.startDate = new Date(this.state.oldStartDate), this.state.endDate = this.state.oldEndDate ? new Date(this.state.oldEndDate) : null);
1449
+ }
1450
+ triggerCallbackIfChanged() {
1451
+ const t = !u(
1452
+ this.state.startDate,
1453
+ this.state.oldStartDate,
1454
+ "day"
1455
+ ), e = this.state.endDate && this.state.oldEndDate && !u(this.state.endDate, this.state.oldEndDate, "day");
1456
+ (t || e) && this.callback(
1457
+ new Date(this.state.startDate),
1458
+ this.state.endDate ? new Date(this.state.endDate) : new Date(this.state.startDate),
1459
+ this.state.chosenLabel || void 0
1460
+ );
1461
+ }
1462
+ roundToIncrement(t) {
1463
+ if (!this.options.timePickerIncrement) return;
1464
+ const e = Math.round(t.getMinutes() / this.options.timePickerIncrement) * this.options.timePickerIncrement;
1465
+ t.setMinutes(e);
1466
+ }
1467
+ dispatchShowEvent() {
1468
+ this.eventService.dispatchEvent(this.element, "show.daterangepicker", this);
1469
+ }
1470
+ dispatchHideEvent() {
1471
+ this.eventService.dispatchEvent(this.element, "hide.daterangepicker", this);
1472
+ }
1473
+ cleanup() {
1474
+ var t;
1475
+ this.removeDocumentListeners(), this.themeService.cleanup(), this.eventService.cleanup(), this.keyboardService.cleanup(), (t = this.container) != null && t.parentNode && this.container.parentNode.removeChild(this.container);
1476
+ }
1477
+ handleKeyboardDateSelect(t) {
1478
+ console.log("DateX: Received date from keyboard:", t.toDateString()), console.log("DateX: Received date day:", t.getDate());
1479
+ const e = this.validationService.validateDate(t);
1480
+ if (!e.isValid) {
1481
+ this.showValidationError(e.error, e.errorCode);
1482
+ return;
1071
1483
  }
1072
- i === "up" ? this.container.classList.add("drop-up") : this.container.classList.remove("drop-up");
1073
- let o;
1074
- this.options.opens === "left" ? (o = t.right - a, o < 9 && (o = 9)) : this.options.opens === "center" ? (o = t.left + t.width / 2 - a / 2, o < 9 ? o = 9 : o + a > window.innerWidth - 9 && (o = window.innerWidth - a - 9)) : (o = t.left, o + a > window.innerWidth - 9 && (o = window.innerWidth - a - 9)), o < 9 && (o = 9), e < 9 && (e = 9), this.container.style.top = `${e}px`, this.container.style.left = `${o}px`, this.container.style.right = "auto", this.container.style.zIndex = "99999";
1075
- }
1076
- // Event handlers
1077
- clickRange(t) {
1078
- const e = t.target, i = e.dataset.rangeKey;
1079
- if (!i) return;
1080
- if (this.container.querySelectorAll(".ranges li").forEach((n) => n.classList.remove("active")), e.classList.add("active"), this.state.chosenLabel = i, i === this.locale.customRangeLabel)
1081
- this.showCalendars();
1082
- else {
1083
- const n = this.options.ranges[i];
1084
- if (n) {
1085
- const [o, r] = n;
1086
- this.state.startDate = new Date(o), this.state.endDate = new Date(r), !this.options.alwaysShowCalendars && Object.keys(this.options.ranges).length === 0 ? this.hideCalendars() : this.showCalendars(), this.updateView(), this.options.autoApply && this.clickApply(t);
1484
+ this.state.hoverDate = null, this.state.endDate || g(t, this.state.startDate) ? (this.state.endDate = null, this.setStartDate(t)) : (this.setEndDate(t), this.options.autoApply && (this.calculateChosenLabel(), this.handleApplyClick())), this.options.singleDatePicker && (this.setEndDate(this.state.startDate), this.options.autoApply && this.handleApplyClick()), this.updateDateClasses();
1485
+ }
1486
+ clearSelection() {
1487
+ const t = /* @__PURE__ */ new Date();
1488
+ this.state.startDate = t, this.state.endDate = null, this.state.chosenLabel = null, this.updateView();
1489
+ }
1490
+ showValidationError(t, e) {
1491
+ var a;
1492
+ (a = this.options.events) != null && a.onValidationError && this.options.events.onValidationError(t, e), console.warn(`DateX Validation Error: ${t} (${e})`);
1493
+ }
1494
+ setupEventListeners() {
1495
+ this.setupElementEvents(), this.setupContainerEvents();
1496
+ }
1497
+ setupElementEvents() {
1498
+ this.isInputOrButton() ? (this.eventService.addEventHandler(
1499
+ this.element,
1500
+ "click",
1501
+ this.show.bind(this)
1502
+ ), this.eventService.addEventHandler(
1503
+ this.element,
1504
+ "focus",
1505
+ this.show.bind(this)
1506
+ ), this.eventService.addEventHandler(
1507
+ this.element,
1508
+ "keyup",
1509
+ this.handleElementChange.bind(this)
1510
+ ), this.eventService.addEventHandler(
1511
+ this.element,
1512
+ "keydown",
1513
+ this.handleKeydown.bind(this)
1514
+ )) : this.eventService.addEventHandler(
1515
+ this.element,
1516
+ "click",
1517
+ this.toggle.bind(this)
1518
+ );
1519
+ }
1520
+ setupContainerEvents() {
1521
+ this.eventService.addEventHandler(
1522
+ this.container,
1523
+ "click",
1524
+ this.handleContainerClick.bind(this)
1525
+ ), this.eventService.addEventHandler(
1526
+ this.container,
1527
+ "mouseover",
1528
+ this.handleContainerMouseOver.bind(this)
1529
+ ), this.eventService.addEventHandler(
1530
+ this.container,
1531
+ "mouseleave",
1532
+ this.handleContainerMouseLeave.bind(this)
1533
+ ), this.eventService.addEventHandler(
1534
+ this.container,
1535
+ "change",
1536
+ this.handleContainerChange.bind(this)
1537
+ );
1538
+ }
1539
+ isInputOrButton() {
1540
+ return this.element.tagName === "INPUT" || this.element.tagName === "BUTTON";
1541
+ }
1542
+ handleContainerClick(t) {
1543
+ const e = t.target;
1544
+ e.tagName === "SELECT" || e.closest("select") || (e.matches(".ranges li") ? this.handleRangeClick(t) : e.matches(".applyBtn") ? this.handleApplyClick() : e.matches(".cancelBtn") ? this.handleCancelClick() : e.matches(".prev") ? this.handlePrevClick(t) : e.matches(".next") ? this.handleNextClick(t) : e.matches("td.available") && this.handleDateClick(t));
1545
+ }
1546
+ handleContainerMouseOver(t) {
1547
+ t.target.matches("td.available") && this.handleDateHover(t);
1548
+ }
1549
+ handleContainerMouseLeave() {
1550
+ this.state.hoverDate && (this.state.hoverDate = null, this.updateDateClasses());
1551
+ }
1552
+ handleContainerChange(t) {
1553
+ const e = t.target;
1554
+ e.matches("select.monthselect, select.yearselect") ? this.handleMonthYearChange(t) : e.matches(
1555
+ "select.hourselect, select.minuteselect, select.secondselect, select.ampmselect"
1556
+ ) && this.handleTimeChange(t);
1557
+ }
1558
+ handleOutsideClick(t) {
1559
+ const e = t.target;
1560
+ this.element.contains(e) || this.container.contains(e) || e.closest(".datex-picker") || e.tagName === "SELECT" || e.closest("select") || (this.hide(), this.eventService.dispatchEvent(
1561
+ this.element,
1562
+ "outsideClick.daterangepicker"
1563
+ ));
1564
+ }
1565
+ handleOutsideFocus(t) {
1566
+ const e = t.target;
1567
+ this.element.contains(e) || this.container.contains(e) || e.closest(".datex-picker") || setTimeout(() => {
1568
+ const a = document.activeElement;
1569
+ a && !this.element.contains(a) && !this.container.contains(a) && !a.closest(".datex-picker") && this.hide();
1570
+ }, 50);
1571
+ }
1572
+ handleElementChange() {
1573
+ var s;
1574
+ if (!this.isInputOrButton()) return;
1575
+ const t = this.element;
1576
+ if (!((s = t.value) != null && s.length)) return;
1577
+ const e = t.value.split(this.locale.separator), { startDate: a, endDate: i } = this.parseDateParts(e);
1578
+ a && y(a) && i && y(i) && (this.setStartDate(a), this.setEndDate(i), this.updateView());
1579
+ }
1580
+ parseDateParts(t) {
1581
+ let e = null, a = null;
1582
+ return t.length === 2 ? (e = b(t[0].trim(), this.locale.format), a = b(t[1].trim(), this.locale.format)) : (this.options.singleDatePicker || t.length === 1) && (e = b(t[0].trim(), this.locale.format), a = e), { startDate: e, endDate: a };
1583
+ }
1584
+ handleKeydown(t) {
1585
+ t.key === "Tab" || t.key === "Enter" ? this.hide() : t.key === "Escape" && (t.preventDefault(), t.stopPropagation(), this.hide());
1586
+ }
1587
+ // Event handler implementations
1588
+ handleRangeClick(t) {
1589
+ const a = t.target.dataset.rangeKey;
1590
+ if (a)
1591
+ if (this.state.chosenLabel = a, this.updateActiveRange(a), a === this.locale.customRangeLabel)
1592
+ this.showCalendars();
1593
+ else {
1594
+ const i = this.options.ranges[a];
1595
+ if (i) {
1596
+ const [s, r] = i;
1597
+ this.state.startDate = new Date(s), this.state.endDate = new Date(r), this.showCalendars(), this.updateView(), this.options.autoApply && this.handleApplyClick();
1598
+ }
1087
1599
  }
1088
- }
1089
1600
  }
1090
- clickPrev(t) {
1091
- const i = t.target.closest(".drp-calendar");
1092
- i && (i.classList.contains("left") ? (this.state.leftCalendar.month = y(
1601
+ handleApplyClick() {
1602
+ this.hide(), this.eventService.dispatchEvent(this.element, "apply.daterangepicker");
1603
+ }
1604
+ handleCancelClick() {
1605
+ this.state.startDate = new Date(this.state.oldStartDate), this.state.endDate = this.state.oldEndDate ? new Date(this.state.oldEndDate) : null, this.hide(), this.eventService.dispatchEvent(this.element, "cancel.daterangepicker");
1606
+ }
1607
+ handlePrevClick(t) {
1608
+ const a = t.target.closest(".drp-calendar");
1609
+ a && (a.classList.contains("left") ? (this.state.leftCalendar.month = f(
1093
1610
  this.state.leftCalendar.month,
1094
1611
  -1
1095
- ), this.options.linkedCalendars && (this.state.rightCalendar.month = y(
1612
+ ), this.options.linkedCalendars && (this.state.rightCalendar.month = f(
1096
1613
  this.state.rightCalendar.month,
1097
1614
  -1
1098
- ))) : this.state.rightCalendar.month = y(
1615
+ ))) : this.state.rightCalendar.month = f(
1099
1616
  this.state.rightCalendar.month,
1100
1617
  -1
1101
1618
  ), this.updateCalendars());
1102
1619
  }
1103
- clickNext(t) {
1104
- const i = t.target.closest(".drp-calendar");
1105
- i && (i.classList.contains("left") ? this.state.leftCalendar.month = y(
1620
+ handleNextClick(t) {
1621
+ const a = t.target.closest(".drp-calendar");
1622
+ a && (a.classList.contains("left") ? this.state.leftCalendar.month = f(
1106
1623
  this.state.leftCalendar.month,
1107
1624
  1
1108
- ) : (this.state.rightCalendar.month = y(
1625
+ ) : (this.state.rightCalendar.month = f(
1109
1626
  this.state.rightCalendar.month,
1110
1627
  1
1111
- ), this.options.linkedCalendars && (this.state.leftCalendar.month = y(
1628
+ ), this.options.linkedCalendars && (this.state.leftCalendar.month = f(
1112
1629
  this.state.leftCalendar.month,
1113
1630
  1
1114
1631
  ))), this.updateCalendars());
1115
1632
  }
1116
- clickDate(t) {
1633
+ handleDateClick(t) {
1634
+ var r, n;
1117
1635
  const e = t.target;
1118
1636
  if (!e.classList.contains("available")) return;
1119
- const i = e.dataset.date;
1120
- if (!i) return;
1121
- const a = C(i, "YYYY-MM-DD");
1122
- if (S(a)) {
1123
- if (this.options.timePicker) {
1124
- const n = e.closest(".drp-calendar");
1125
- if (n) {
1126
- const o = n.querySelector(
1127
- ".hourselect"
1128
- ), r = n.querySelector(
1129
- ".minuteselect"
1130
- ), f = n.querySelector(
1131
- ".secondselect"
1132
- ), h = n.querySelector(
1133
- ".ampmselect"
1637
+ const a = e.dataset.date;
1638
+ if (!a) return;
1639
+ const i = b(a, "YYYY-MM-DD");
1640
+ if (!y(i)) return;
1641
+ const s = this.validationService.validateDate(i);
1642
+ if (!s.isValid) {
1643
+ this.showValidationError(s.error, s.errorCode);
1644
+ return;
1645
+ }
1646
+ if (!((r = this.options.events) != null && r.beforeDateSelect && !this.options.events.beforeDateSelect(i))) {
1647
+ if (this.applyTimeToDate(i, e), this.state.hoverDate = null, this.state.endDate || g(i, this.state.startDate))
1648
+ this.state.endDate = null, this.setStartDate(i);
1649
+ else {
1650
+ if (this.setEndDate(i), this.state.startDate && this.state.endDate) {
1651
+ const o = this.validationService.validateDateRange(
1652
+ this.state.startDate,
1653
+ this.state.endDate
1134
1654
  );
1135
- if (o) {
1136
- let d = parseInt(o.value, 10);
1137
- if (!this.options.timePicker24Hour && h) {
1138
- const p = h.value;
1139
- p === "PM" && d < 12 && (d += 12), p === "AM" && d === 12 && (d = 0);
1140
- }
1141
- a.setHours(d);
1655
+ if (!o.isValid) {
1656
+ this.showValidationError(
1657
+ o.error,
1658
+ o.errorCode
1659
+ ), this.state.endDate = null, this.updateDateClasses();
1660
+ return;
1142
1661
  }
1143
- if (r) {
1144
- let d = parseInt(r.value, 10);
1145
- if (isNaN(d)) {
1146
- const p = r.options[r.options.length - 1];
1147
- d = parseInt(p.value, 10);
1148
- }
1149
- a.setMinutes(d);
1150
- }
1151
- this.options.timePickerSeconds && f && a.setSeconds(parseInt(f.value, 10));
1152
1662
  }
1663
+ this.options.autoApply && (this.calculateChosenLabel(), this.handleApplyClick());
1153
1664
  }
1154
- this.state.hoverDate = null, this.state.endDate || g(a, this.state.startDate) ? (this.state.endDate = null, this.setStartDate(a)) : (this.setEndDate(a), this.options.autoApply && (this.calculateChosenLabel(), this.clickApply(t))), this.options.singleDatePicker && (this.setEndDate(this.state.startDate), this.options.autoApply && this.clickApply(t)), this.updateDateClasses();
1665
+ this.options.singleDatePicker && (this.setEndDate(this.state.startDate), this.options.autoApply && this.handleApplyClick()), (n = this.options.events) != null && n.onDateSelect && this.options.events.onDateSelect(i), this.updateDateClasses();
1155
1666
  }
1156
1667
  }
1157
- hoverDate(t) {
1668
+ handleDateHover(t) {
1158
1669
  const e = t.target;
1159
1670
  if (!e.classList.contains("available")) return;
1160
- const i = e.dataset.date;
1161
- if (!i) return;
1162
- const a = C(i, "YYYY-MM-DD");
1163
- S(a) && !this.state.endDate && !g(a, this.state.startDate) && (this.state.hoverDate = a, this.updateDateClasses());
1671
+ const a = e.dataset.date;
1672
+ if (!a) return;
1673
+ const i = b(a, "YYYY-MM-DD");
1674
+ y(i) && !this.state.endDate && !g(i, this.state.startDate) && (this.state.hoverDate = i, this.updateDateClasses());
1164
1675
  }
1165
- updateDateClasses() {
1166
- this.container.querySelectorAll("td[data-date]").forEach((e) => {
1167
- const i = e.dataset.date;
1168
- if (!i) return;
1169
- const a = C(i, "YYYY-MM-DD");
1170
- if (!S(a)) return;
1171
- e.classList.remove("in-range", "end-date", "start-date", "active");
1172
- const n = this.state.startDate, o = this.state.endDate, r = this.state.hoverDate;
1173
- if (n && x(a, n, "day") && e.classList.add("active", "start-date"), o && x(a, o, "day") && e.classList.add("active", "end-date"), n && o && b(a, n) && g(a, o) && e.classList.add("in-range"), n && r && !o) {
1174
- const f = g(r, n) ? r : n, h = g(r, n) ? n : r;
1175
- x(a, r, "day") ? e.classList.add("end-date") : b(a, f) && g(a, h) && e.classList.add("in-range");
1676
+ handleMonthYearChange(t) {
1677
+ const a = t.target.closest(".drp-calendar");
1678
+ if (!a) return;
1679
+ const i = a.classList.contains("left"), s = a.querySelector(
1680
+ ".monthselect"
1681
+ ), r = a.querySelector(
1682
+ ".yearselect"
1683
+ );
1684
+ if (!s || !r) return;
1685
+ const n = parseInt(s.value, 10), o = parseInt(r.value, 10), c = new Date(o, n, 1);
1686
+ i ? (this.state.leftCalendar.month = c, this.options.linkedCalendars && (this.state.rightCalendar.month = f(c, 1))) : (this.state.rightCalendar.month = c, this.options.linkedCalendars && (this.state.leftCalendar.month = f(c, -1))), this.updateCalendars();
1687
+ }
1688
+ handleTimeChange(t) {
1689
+ const a = t.target.closest(".drp-calendar");
1690
+ if (!a) return;
1691
+ const i = a.classList.contains("left"), s = i ? this.state.startDate : this.state.endDate || this.state.startDate, r = a.querySelector(
1692
+ ".hourselect"
1693
+ ), n = a.querySelector(
1694
+ ".minuteselect"
1695
+ ), o = a.querySelector(
1696
+ ".secondselect"
1697
+ ), c = a.querySelector(
1698
+ ".ampmselect"
1699
+ );
1700
+ if (!r || !n) return;
1701
+ let d = parseInt(r.value, 10);
1702
+ const m = parseInt(n.value, 10) || 0, p = o ? parseInt(o.value, 10) : 0;
1703
+ if (!this.options.timePicker24Hour && c) {
1704
+ const D = c.value;
1705
+ D === "PM" && d < 12 && (d += 12), D === "AM" && d === 12 && (d = 0);
1706
+ }
1707
+ const h = new Date(s);
1708
+ if (h.setHours(d), h.setMinutes(m), h.setSeconds(p), this.options.timePickerIncrement && this.roundToIncrement(h), !(this.options.minDate && h < this.options.minDate) && !(this.options.maxDate && h > this.options.maxDate)) {
1709
+ if (this.validationService) {
1710
+ const D = this.validationService.validateDate(h);
1711
+ if (!D.isValid) {
1712
+ this.showValidationError(D.error, D.errorCode);
1713
+ return;
1714
+ }
1176
1715
  }
1716
+ i ? (this.state.startDate = h, this.options.singleDatePicker ? this.state.endDate = h : this.state.endDate && this.state.endDate.toDateString() === h.toDateString() && this.state.endDate < h && (this.state.endDate = new Date(h))) : this.state.endDate && (this.state.endDate = h), this.updateSelectedDisplay(), this.updateCalendars(), this.updateFormInputs();
1717
+ }
1718
+ }
1719
+ // View update methods
1720
+ updateView() {
1721
+ this.updateMonthsInView(), this.updateCalendars(), this.updateFormInputs(), this.updateSelectedDisplay(), this.calculateChosenLabel(), this.options.timePicker && this.updateTimePickerControls();
1722
+ }
1723
+ updateTimePickerControls() {
1724
+ const t = this.container.querySelectorAll(
1725
+ ".right .calendar-time select"
1726
+ );
1727
+ this.state.endDate ? t.forEach((e) => {
1728
+ e.disabled = !1, e.classList.remove("disabled");
1729
+ }) : t.forEach((e) => {
1730
+ e.disabled = !0, e.classList.add("disabled");
1177
1731
  });
1178
1732
  }
1179
- clickApply(t) {
1180
- this.hide(), this.dispatchEvent("apply.daterangepicker");
1733
+ updateMonthsInView() {
1734
+ this.state.endDate ? (this.state.leftCalendar.month = x(this.state.startDate), !this.options.linkedCalendars && (this.state.endDate.getMonth() !== this.state.startDate.getMonth() || this.state.endDate.getFullYear() !== this.state.startDate.getFullYear()) ? this.state.rightCalendar.month = x(this.state.endDate) : this.state.rightCalendar.month = f(
1735
+ this.state.leftCalendar.month,
1736
+ 1
1737
+ )) : (this.state.leftCalendar.month = x(this.state.startDate), this.state.rightCalendar.month = f(
1738
+ this.state.leftCalendar.month,
1739
+ 1
1740
+ ));
1181
1741
  }
1182
- clickCancel(t) {
1183
- this.state.startDate = new Date(this.state.oldStartDate), this.state.endDate = this.state.oldEndDate ? new Date(this.state.oldEndDate) : null, this.hide(), this.dispatchEvent("cancel.daterangepicker");
1742
+ updateCalendars() {
1743
+ this.renderCalendar("left"), this.options.singleDatePicker || this.renderCalendar("right");
1184
1744
  }
1185
- monthOrYearChanged(t) {
1186
- const i = t.target.closest(".drp-calendar");
1187
- if (!i)
1188
- return;
1189
- const a = i.classList.contains("left"), n = i.querySelector(
1190
- ".monthselect"
1191
- ), o = i.querySelector(
1192
- ".yearselect"
1745
+ renderCalendar(t) {
1746
+ const e = t === "left" ? this.state.leftCalendar : this.state.rightCalendar, a = this.container.querySelector(
1747
+ `.drp-calendar.${t} .calendar-table`
1193
1748
  );
1194
- if (!n || !o)
1195
- return;
1196
- const r = parseInt(n.value, 10), f = parseInt(o.value, 10), h = new Date(f, r, 1);
1197
- a ? (this.state.leftCalendar.month = h, this.options.linkedCalendars && (this.state.rightCalendar.month = y(h, 1))) : (this.state.rightCalendar.month = h, this.options.linkedCalendars && (this.state.leftCalendar.month = y(h, -1))), this.updateCalendars();
1749
+ e.calendar = this.calendarService.buildCalendarMatrix(
1750
+ e.month
1751
+ );
1752
+ const i = this.calendarService.canNavigatePrevious(e.month), s = this.calendarService.canNavigateNext(e.month), r = this.calendarService.renderCalendarHTML(
1753
+ e,
1754
+ t,
1755
+ this.state.startDate,
1756
+ this.state.endDate,
1757
+ i,
1758
+ s
1759
+ );
1760
+ a.innerHTML = r;
1198
1761
  }
1199
- elementChanged() {
1200
- if (this.element.tagName !== "INPUT") return;
1201
- const t = this.element;
1202
- if (!t.value || !t.value.length) return;
1203
- const e = t.value.split(this.locale.separator);
1204
- let i = null, a = null;
1205
- e.length === 2 ? (i = C(e[0].trim(), this.locale.format), a = C(e[1].trim(), this.locale.format)) : (this.options.singleDatePicker || e.length === 1) && (i = C(e[0].trim(), this.locale.format), a = i), i && S(i) && a && S(a) && (this.setStartDate(i), this.setEndDate(a), this.updateView());
1762
+ updateFormInputs() {
1763
+ const t = this.container.querySelector(
1764
+ ".applyBtn"
1765
+ ), e = this.options.singleDatePicker || this.state.endDate && (g(this.state.startDate, this.state.endDate) || u(this.state.startDate, this.state.endDate, "day"));
1766
+ t.disabled = !e;
1206
1767
  }
1207
- keydown(t) {
1208
- (t.key === "Tab" || t.key === "Enter") && this.hide(), t.key === "Escape" && (t.preventDefault(), t.stopPropagation(), this.hide());
1768
+ updateSelectedDisplay() {
1769
+ const t = this.container.querySelector(".drp-selected");
1770
+ let e = C(this.state.startDate, this.locale.format);
1771
+ !this.options.singleDatePicker && this.state.endDate && (e += this.locale.separator + C(this.state.endDate, this.locale.format)), t.textContent = e;
1209
1772
  }
1210
- showCalendars() {
1211
- this.container.classList.add("show-calendar"), this.move(), this.dispatchEvent("showCalendar.daterangepicker");
1773
+ updateElement() {
1774
+ if (this.element.tagName === "INPUT" && this.options.autoUpdateInput) {
1775
+ const t = this.element;
1776
+ let e = C(this.state.startDate, this.locale.format);
1777
+ !this.options.singleDatePicker && this.state.endDate && (e += this.locale.separator + C(this.state.endDate, this.locale.format)), e !== t.value && (t.value = e, this.eventService.dispatchEvent(this.element, "change"));
1778
+ }
1212
1779
  }
1213
- hideCalendars() {
1214
- this.container.classList.remove("show-calendar"), this.dispatchEvent("hideCalendar.daterangepicker");
1780
+ renderRanges() {
1781
+ const t = this.container.querySelector(".ranges");
1782
+ t.innerHTML = this.createRangeService().renderRanges();
1215
1783
  }
1216
1784
  calculateChosenLabel() {
1217
- let t = !0, e = null;
1218
- for (const [a, [n, o]] of Object.entries(
1219
- this.options.ranges
1220
- )) {
1221
- const r = x(this.state.startDate, n, "day");
1222
- let f = !1;
1223
- if (this.state.endDate ? f = x(this.state.endDate, o, "day") : f = x(this.state.startDate, o, "day"), r && f) {
1224
- const h = Math.abs(o.getTime() - n.getTime()) / 864e5 + 1;
1225
- (!e || h > e.days) && (e = { label: a, days: h });
1226
- }
1227
- }
1228
- if (this.container.querySelectorAll(".ranges li").forEach((a) => a.classList.remove("active")), e) {
1229
- t = !1, this.state.chosenLabel = e.label;
1230
- const a = this.container.querySelector(
1231
- `[data-range-key="${e.label}"]`
1232
- );
1233
- a && a.classList.add("active");
1234
- }
1235
- if (t)
1236
- if (this.options.showCustomRangeLabel) {
1237
- this.state.chosenLabel = this.locale.customRangeLabel;
1238
- const a = this.container.querySelector(
1239
- `[data-range-key="${this.locale.customRangeLabel}"]`
1240
- );
1241
- a && a.classList.add("active");
1242
- } else
1243
- this.state.chosenLabel = null;
1244
- Object.keys(this.options.ranges).length > 0 && this.showCalendars();
1245
- }
1246
- // Public API
1247
- setStartDate(t) {
1248
- if (!this.options.timePicker)
1249
- this.state.startDate = M(t);
1250
- else if (this.state.startDate = new Date(t), this.options.timePickerIncrement) {
1251
- const e = Math.round(
1252
- this.state.startDate.getMinutes() / this.options.timePickerIncrement
1253
- ) * this.options.timePickerIncrement;
1254
- this.state.startDate.setMinutes(e);
1255
- }
1256
- this.updateView();
1785
+ const t = this.createRangeService();
1786
+ this.state.chosenLabel = t.calculateChosenLabel(
1787
+ this.state.startDate,
1788
+ this.state.endDate
1789
+ ), t.updateActiveRange(this.container, this.state.chosenLabel), Object.keys(this.options.ranges).length > 0 && this.showCalendars();
1257
1790
  }
1258
- setEndDate(t) {
1259
- if (!this.options.timePicker)
1260
- this.state.endDate = E(t);
1261
- else if (this.state.endDate = new Date(t), this.options.timePickerIncrement) {
1262
- const e = Math.round(
1263
- this.state.endDate.getMinutes() / this.options.timePickerIncrement
1264
- ) * this.options.timePickerIncrement;
1265
- this.state.endDate.setMinutes(e);
1266
- }
1267
- this.updateView();
1791
+ updateActiveRange(t) {
1792
+ this.createRangeService().updateActiveRange(this.container, t);
1268
1793
  }
1269
- getStartDate() {
1270
- return new Date(this.state.startDate);
1794
+ showCalendars() {
1795
+ this.container.classList.add("show-calendar"), this.positionContainer(), this.eventService.dispatchEvent(
1796
+ this.element,
1797
+ "showCalendar.daterangepicker"
1798
+ );
1271
1799
  }
1272
- getEndDate() {
1273
- return this.state.endDate ? new Date(this.state.endDate) : null;
1800
+ updateDateClasses() {
1801
+ this.container.querySelectorAll("td[data-date]").forEach((e) => {
1802
+ const a = e.dataset.date;
1803
+ if (!a) return;
1804
+ const i = b(a, "YYYY-MM-DD");
1805
+ if (!y(i)) return;
1806
+ e.classList.remove("in-range", "end-date", "start-date", "active");
1807
+ const s = this.state.startDate, r = this.state.endDate, n = this.state.hoverDate;
1808
+ if (s && u(i, s, "day") && e.classList.add("active", "start-date"), r && u(i, r, "day") && e.classList.add("active", "end-date"), s && r && k(i, s) && g(i, r) && e.classList.add("in-range"), s && n && !r) {
1809
+ const o = g(n, s) ? n : s, c = g(n, s) ? s : n;
1810
+ u(i, n, "day") ? e.classList.add("end-date") : k(i, o) && g(i, c) && e.classList.add("in-range");
1811
+ }
1812
+ });
1274
1813
  }
1275
- remove() {
1276
- if (this.removeDocumentListeners(), this.container && this.container.dataset.themeStyleId) {
1277
- const t = document.getElementById(
1278
- this.container.dataset.themeStyleId
1279
- );
1280
- t && t.remove();
1281
- }
1282
- this.boundHandlers.forEach((t, e) => {
1283
- }), this.boundHandlers.clear(), this.container && this.container.parentNode && this.container.parentNode.removeChild(this.container);
1284
- }
1285
- updateRanges(t) {
1286
- if (typeof t == "object") {
1287
- this.options.ranges = {};
1288
- for (const [e, i] of Object.entries(t)) {
1289
- let a, n;
1290
- typeof i[0] == "string" ? a = C(i[0], this.locale.format) : a = new Date(i[0]), typeof i[1] == "string" ? n = C(i[1], this.locale.format) : n = new Date(i[1]), this.options.minDate && g(a, this.options.minDate) && (a = new Date(this.options.minDate));
1291
- let o = this.options.maxDate;
1292
- if (this.options.maxSpan && o) {
1293
- const r = $(a, this.options.maxSpan.days || 0);
1294
- b(r, o) && (o = r);
1295
- }
1296
- o && b(n, o) && (n = new Date(o)), !(this.options.minDate && g(n, this.options.minDate) || o && b(a, o)) && (this.options.ranges[e] = [a, n]);
1814
+ applyTimeToDate(t, e) {
1815
+ if (!this.options.timePicker) return;
1816
+ const a = e.closest(".drp-calendar");
1817
+ if (!a) return;
1818
+ const i = a.querySelector(
1819
+ ".hourselect"
1820
+ ), s = a.querySelector(
1821
+ ".minuteselect"
1822
+ ), r = a.querySelector(
1823
+ ".secondselect"
1824
+ ), n = a.querySelector(
1825
+ ".ampmselect"
1826
+ );
1827
+ if (i) {
1828
+ let o = parseInt(i.value, 10);
1829
+ if (!this.options.timePicker24Hour && n) {
1830
+ const c = n.value;
1831
+ c === "PM" && o < 12 && (o += 12), c === "AM" && o === 12 && (o = 0);
1297
1832
  }
1298
- this.renderRanges();
1833
+ t.setHours(o);
1834
+ }
1835
+ if (s) {
1836
+ const o = parseInt(s.value, 10) || 0;
1837
+ t.setMinutes(o);
1299
1838
  }
1839
+ this.options.timePickerSeconds && r && t.setSeconds(parseInt(r.value, 10));
1300
1840
  }
1301
- dispatchEvent(t) {
1302
- const e = new CustomEvent(t, {
1303
- bubbles: !0,
1304
- detail: this
1305
- });
1306
- this.element.dispatchEvent(e);
1841
+ createRangeService() {
1842
+ return {
1843
+ renderRanges: () => {
1844
+ let t = "<ul>";
1845
+ for (const [e] of Object.entries(this.options.ranges))
1846
+ t += `<li data-range-key="${e}">${e}</li>`;
1847
+ return this.options.showCustomRangeLabel && (t += `<li data-range-key="${this.locale.customRangeLabel}">${this.locale.customRangeLabel}</li>`), t += "</ul>", t;
1848
+ },
1849
+ calculateChosenLabel: (t, e) => {
1850
+ let a = null;
1851
+ for (const [i, [s, r]] of Object.entries(
1852
+ this.options.ranges
1853
+ )) {
1854
+ const n = u(t, s, "day");
1855
+ let o = !1;
1856
+ if (e ? o = u(e, r, "day") : o = u(t, r, "day"), n && o) {
1857
+ const c = Math.abs(r.getTime() - s.getTime()) / 864e5 + 1;
1858
+ (!a || c > a.days) && (a = { label: i, days: c });
1859
+ }
1860
+ }
1861
+ return a ? a.label : this.options.showCustomRangeLabel ? this.locale.customRangeLabel : null;
1862
+ },
1863
+ updateActiveRange: (t, e) => {
1864
+ if (t.querySelectorAll(".ranges li").forEach((i) => i.classList.remove("active")), e) {
1865
+ const i = t.querySelector(
1866
+ `[data-range-key="${e}"]`
1867
+ );
1868
+ i == null || i.classList.add("active");
1869
+ }
1870
+ }
1871
+ };
1307
1872
  }
1308
1873
  }
1309
1874
  export {
1310
- I as BOOTSTRAP_THEME,
1311
- L as DEFAULT_THEME,
1312
- q as Datex,
1313
- T as MATERIAL_THEME,
1875
+ B as BOOTSTRAP_THEME,
1876
+ E as DEFAULT_THEME,
1877
+ O as Datex,
1878
+ R as MATERIAL_THEME,
1314
1879
  Y as SPANISH_LOCALE,
1315
- A as SPANISH_LOCALE_WITH_TIME
1880
+ V as SPANISH_LOCALE_WITH_TIME,
1881
+ f as addMonths,
1882
+ S as endOfDay,
1883
+ C as formatDate,
1884
+ x as getStartOfMonth,
1885
+ k as isAfterDate,
1886
+ g as isBeforeDate,
1887
+ u as isSameDate,
1888
+ y as isValidDate,
1889
+ b as parseDate,
1890
+ w as startOfDay
1316
1891
  };