ngxsmk-datepicker 1.3.5 → 1.3.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,152 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, inject, ElementRef, HostListener, Output, Input, Component, HostBinding } from '@angular/core';
2
+ import { EventEmitter, inject, ElementRef, HostListener, Output, Input, Component, forwardRef, HostBinding, ChangeDetectionStrategy } from '@angular/core';
3
3
  import * as i1 from '@angular/common';
4
- import { CommonModule } from '@angular/common';
5
- import { FormsModule } from '@angular/forms';
4
+ import { CommonModule, DatePipe } from '@angular/common';
5
+ import { FormsModule, ReactiveFormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
6
+
7
+ /**
8
+ * Date utility functions for ngxsmk-datepicker
9
+ * Extracted to improve tree-shaking and reduce bundle size
10
+ */
11
+ function getStartOfDay(d) {
12
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
13
+ }
14
+ function getEndOfDay(d) {
15
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
16
+ }
17
+ function addMonths(d, months) {
18
+ const newDate = new Date(d);
19
+ newDate.setMonth(d.getMonth() + months);
20
+ return newDate;
21
+ }
22
+ function subtractDays(d, days) {
23
+ const newDate = new Date(d);
24
+ newDate.setDate(d.getDate() - days);
25
+ return newDate;
26
+ }
27
+ function getStartOfMonth(d) {
28
+ return new Date(d.getFullYear(), d.getMonth(), 1);
29
+ }
30
+ function getEndOfMonth(d) {
31
+ return new Date(d.getFullYear(), d.getMonth() + 1, 0);
32
+ }
33
+ function isSameDay(d1, d2) {
34
+ if (!d1 || !d2)
35
+ return false;
36
+ return (d1.getFullYear() === d2.getFullYear() &&
37
+ d1.getMonth() === d2.getMonth() &&
38
+ d1.getDate() === d2.getDate());
39
+ }
40
+ function normalizeDate(date) {
41
+ if (!date)
42
+ return null;
43
+ const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date.toDate ? date.toDate() : date);
44
+ if (isNaN(d.getTime()))
45
+ return null;
46
+ return d;
47
+ }
48
+
49
+ /**
50
+ * Calendar utility functions for ngxsmk-datepicker
51
+ * Optimized for performance and tree-shaking
52
+ */
53
+ /**
54
+ * Generate month options for dropdown
55
+ */
56
+ function generateMonthOptions(locale, year) {
57
+ return Array.from({ length: 12 }).map((_, i) => ({
58
+ label: new Date(year, i, 1).toLocaleDateString(locale, { month: 'long' }),
59
+ value: i,
60
+ }));
61
+ }
62
+ /**
63
+ * Generate year options for dropdown
64
+ */
65
+ function generateYearOptions(currentYear, range = 10) {
66
+ const startYear = currentYear - range;
67
+ const endYear = currentYear + range;
68
+ const options = [];
69
+ for (let i = startYear; i <= endYear; i++) {
70
+ options.push({ label: `${i}`, value: i });
71
+ }
72
+ return options;
73
+ }
74
+ /**
75
+ * Generate time options for hour/minute dropdowns
76
+ */
77
+ function generateTimeOptions(minuteInterval = 1) {
78
+ const hourOptions = Array.from({ length: 12 }).map((_, i) => ({
79
+ label: (i + 1).toString().padStart(2, '0'),
80
+ value: i + 1,
81
+ }));
82
+ const minuteOptions = [];
83
+ for (let i = 0; i < 60; i += minuteInterval) {
84
+ minuteOptions.push({
85
+ label: i.toString().padStart(2, '0'),
86
+ value: i,
87
+ });
88
+ }
89
+ return { hourOptions, minuteOptions };
90
+ }
91
+ /**
92
+ * Generate week days for calendar header
93
+ */
94
+ function generateWeekDays(locale, firstDayOfWeek = 0) {
95
+ const day = new Date(2024, 0, 7 + firstDayOfWeek);
96
+ return Array.from({ length: 7 }).map(() => {
97
+ const weekDay = new Date(day).toLocaleDateString(locale, { weekday: 'short' });
98
+ day.setDate(day.getDate() + 1);
99
+ return weekDay;
100
+ });
101
+ }
102
+ /**
103
+ * Get first day of week for locale
104
+ */
105
+ function getFirstDayOfWeek(locale) {
106
+ try {
107
+ return (new Intl.Locale(locale).weekInfo?.firstDay || 0) % 7;
108
+ }
109
+ catch (e) {
110
+ return 0;
111
+ }
112
+ }
113
+ /**
114
+ * Convert 12-hour to 24-hour format
115
+ */
116
+ function get24Hour(displayHour, isPm) {
117
+ if (isPm) {
118
+ return displayHour === 12 ? 12 : displayHour + 12;
119
+ }
120
+ return displayHour === 12 ? 0 : displayHour;
121
+ }
122
+ /**
123
+ * Convert 24-hour to 12-hour format
124
+ */
125
+ function update12HourState(fullHour) {
126
+ return {
127
+ isPm: fullHour >= 12,
128
+ displayHour: fullHour % 12 || 12
129
+ };
130
+ }
131
+ /**
132
+ * Process date ranges input
133
+ */
134
+ function processDateRanges(ranges) {
135
+ if (!ranges)
136
+ return null;
137
+ return Object.entries(ranges).reduce((acc, [key, dates]) => {
138
+ const start = normalizeDate(dates[0]);
139
+ const end = normalizeDate(dates[1]);
140
+ if (start && end)
141
+ acc[key] = [start, end];
142
+ return acc;
143
+ }, {});
144
+ }
6
145
 
7
146
  class CustomSelectComponent {
8
147
  constructor() {
9
148
  this.options = [];
149
+ this.disabled = false;
10
150
  this.valueChange = new EventEmitter();
11
151
  this.isOpen = false;
12
152
  this.elementRef = inject(ElementRef);
@@ -20,6 +160,8 @@ class CustomSelectComponent {
20
160
  return selectedOption ? selectedOption.label : '';
21
161
  }
22
162
  toggleDropdown() {
163
+ if (this.disabled)
164
+ return;
23
165
  this.isOpen = !this.isOpen;
24
166
  }
25
167
  selectOption(option) {
@@ -28,9 +170,9 @@ class CustomSelectComponent {
28
170
  this.isOpen = false;
29
171
  }
30
172
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
31
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CustomSelectComponent, isStandalone: true, selector: "app-custom-select", inputs: { options: "options", value: "value" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
173
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CustomSelectComponent, isStandalone: true, selector: "ngxsmk-custom-select", inputs: { options: "options", value: "value", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
32
174
  <div class="ngxsmk-select-container" (click)="toggleDropdown()">
33
- <button type="button" class="ngxsmk-select-display">
175
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
34
176
  <span>{{ displayValue }}</span>
35
177
  <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
36
178
  <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
@@ -49,13 +191,13 @@ class CustomSelectComponent {
49
191
  </div>
50
192
  }
51
193
  </div>
52
- `, isInline: true, styles: [":host{position:relative;display:inline-block}.ngxsmk-select-container{cursor:pointer}.ngxsmk-select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:14px;text-align:left;height:30px}.ngxsmk-arrow-icon{width:12px;height:12px;margin-left:8px}.ngxsmk-options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:9999}.ngxsmk-options-panel ul{list-style:none;padding:4px;margin:0}.ngxsmk-options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.ngxsmk-options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.ngxsmk-options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
194
+ `, isInline: true, styles: [":host{position:relative;display:inline-block}.ngxsmk-select-container{cursor:pointer}.ngxsmk-select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:14px;text-align:left;height:30px}.ngxsmk-select-display:disabled{background-color:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed;opacity:.7}.ngxsmk-arrow-icon{width:12px;height:12px;margin-left:8px}.ngxsmk-options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:9999}.ngxsmk-options-panel ul{list-style:none;padding:4px;margin:0}.ngxsmk-options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.ngxsmk-options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.ngxsmk-options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
53
195
  }
54
196
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, decorators: [{
55
197
  type: Component,
56
- args: [{ selector: 'app-custom-select', standalone: true, imports: [CommonModule], template: `
198
+ args: [{ selector: 'ngxsmk-custom-select', standalone: true, imports: [CommonModule], template: `
57
199
  <div class="ngxsmk-select-container" (click)="toggleDropdown()">
58
- <button type="button" class="ngxsmk-select-display">
200
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
59
201
  <span>{{ displayValue }}</span>
60
202
  <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
61
203
  <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
@@ -74,17 +216,115 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
74
216
  </div>
75
217
  }
76
218
  </div>
77
- `, styles: [":host{position:relative;display:inline-block}.ngxsmk-select-container{cursor:pointer}.ngxsmk-select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:14px;text-align:left;height:30px}.ngxsmk-arrow-icon{width:12px;height:12px;margin-left:8px}.ngxsmk-options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:9999}.ngxsmk-options-panel ul{list-style:none;padding:4px;margin:0}.ngxsmk-options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.ngxsmk-options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.ngxsmk-options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"] }]
219
+ `, styles: [":host{position:relative;display:inline-block}.ngxsmk-select-container{cursor:pointer}.ngxsmk-select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:14px;text-align:left;height:30px}.ngxsmk-select-display:disabled{background-color:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed;opacity:.7}.ngxsmk-arrow-icon{width:12px;height:12px;margin-left:8px}.ngxsmk-options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:9999}.ngxsmk-options-panel ul{list-style:none;padding:4px;margin:0}.ngxsmk-options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.ngxsmk-options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.ngxsmk-options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"] }]
78
220
  }], propDecorators: { options: [{
79
221
  type: Input
80
222
  }], value: [{
81
223
  type: Input
224
+ }], disabled: [{
225
+ type: Input
82
226
  }], valueChange: [{
83
227
  type: Output
84
228
  }], onDocumentClick: [{
85
229
  type: HostListener,
86
230
  args: ['document:click', ['$event']]
87
231
  }] } });
232
+
233
+ /**
234
+ * Performance utilities for ngxsmk-datepicker
235
+ * Optimized for better runtime performance
236
+ */
237
+ /**
238
+ * Memoization decorator for expensive computations
239
+ */
240
+ function memoize(fn, keyGenerator) {
241
+ const cache = new Map();
242
+ return ((...args) => {
243
+ const key = keyGenerator ? keyGenerator(...args) : JSON.stringify(args);
244
+ if (cache.has(key)) {
245
+ return cache.get(key);
246
+ }
247
+ const result = fn(...args);
248
+ cache.set(key, result);
249
+ return result;
250
+ });
251
+ }
252
+ /**
253
+ * Debounce function for performance optimization
254
+ */
255
+ function debounce(func, wait) {
256
+ let timeout = null;
257
+ return (...args) => {
258
+ if (timeout) {
259
+ clearTimeout(timeout);
260
+ }
261
+ timeout = window.setTimeout(() => {
262
+ func(...args);
263
+ }, wait);
264
+ };
265
+ }
266
+ /**
267
+ * Throttle function for performance optimization
268
+ */
269
+ function throttle(func, limit) {
270
+ let inThrottle = false;
271
+ return (...args) => {
272
+ if (!inThrottle) {
273
+ func(...args);
274
+ inThrottle = true;
275
+ window.setTimeout(() => (inThrottle = false), limit);
276
+ }
277
+ };
278
+ }
279
+ /**
280
+ * Create a shallow comparison function for objects
281
+ */
282
+ function shallowEqual(a, b) {
283
+ const keysA = Object.keys(a);
284
+ const keysB = Object.keys(b);
285
+ if (keysA.length !== keysB.length) {
286
+ return false;
287
+ }
288
+ for (const key of keysA) {
289
+ if (a[key] !== b[key]) {
290
+ return false;
291
+ }
292
+ }
293
+ return true;
294
+ }
295
+ /**
296
+ * Optimized date comparison for calendar rendering
297
+ */
298
+ function createDateComparator() {
299
+ const cache = new Map();
300
+ return (date1, date2) => {
301
+ if (!date1 || !date2)
302
+ return date1 === date2;
303
+ const key = `${date1.getTime()}-${date2.getTime()}`;
304
+ if (cache.has(key)) {
305
+ return cache.get(key);
306
+ }
307
+ const result = (date1.getFullYear() === date2.getFullYear() &&
308
+ date1.getMonth() === date2.getMonth() &&
309
+ date1.getDate() === date2.getDate());
310
+ cache.set(key, result);
311
+ return result;
312
+ };
313
+ }
314
+ /**
315
+ * Optimized array filtering with caching
316
+ */
317
+ function createFilteredArray(source, filterFn, cacheKey) {
318
+ const cache = new Map();
319
+ const key = cacheKey || JSON.stringify(source);
320
+ if (cache.has(key)) {
321
+ return cache.get(key);
322
+ }
323
+ const result = source.filter(filterFn);
324
+ cache.set(key, result);
325
+ return result;
326
+ }
327
+
88
328
  class NgxsmkDatepickerComponent {
89
329
  constructor() {
90
330
  this.mode = 'single';
@@ -92,19 +332,31 @@ class NgxsmkDatepickerComponent {
92
332
  this.showRanges = true;
93
333
  this.showTime = false;
94
334
  this.minuteInterval = 1;
95
- this.value = null;
335
+ // NEW: Holiday Provider Inputs
336
+ this.holidayProvider = null;
337
+ this.disableHolidays = false;
338
+ // Popover/Input Mode
339
+ this.placeholder = 'Select Date';
340
+ this.inline = false;
341
+ this.isCalendarOpen = false;
342
+ this._internalValue = null;
96
343
  this._startAtDate = null;
97
344
  this._locale = 'en-US';
98
345
  this.theme = 'light';
346
+ this.onChange = (_) => { };
347
+ this.onTouched = () => { };
348
+ this.disabled = false;
99
349
  this.valueChange = new EventEmitter();
350
+ this.action = new EventEmitter();
100
351
  this._minDate = null;
101
352
  this._maxDate = null;
102
353
  this._ranges = null;
103
354
  this.currentDate = new Date();
104
355
  this.daysInMonth = [];
105
356
  this.weekDays = [];
106
- this.today = new Date();
357
+ this.today = getStartOfDay(new Date());
107
358
  this.selectedDate = null;
359
+ this.selectedDates = [];
108
360
  this.startDate = null;
109
361
  this.endDate = null;
110
362
  this.hoveredDate = null;
@@ -124,52 +376,131 @@ class NgxsmkDatepickerComponent {
124
376
  { label: 'AM', value: false },
125
377
  { label: 'PM', value: true }
126
378
  ];
379
+ // Animation state properties
380
+ this.animateForward = false;
381
+ this.animateBackward = false;
382
+ this.elementRef = inject(ElementRef);
383
+ this.dateComparator = createDateComparator();
127
384
  }
128
385
  set startAt(value) { this._startAtDate = this._normalizeDate(value); }
129
386
  set locale(value) { this._locale = value; }
130
387
  get locale() { return this._locale; }
131
388
  get isDarkMode() { return this.theme === 'dark'; }
389
+ set disabledState(isDisabled) { this.disabled = isDisabled; }
132
390
  set minDate(value) { this._minDate = this._normalizeDate(value); }
133
391
  set maxDate(value) { this._maxDate = this._normalizeDate(value); }
134
392
  set ranges(value) {
135
- if (!value) {
136
- this._ranges = null;
393
+ this._ranges = processDateRanges(value);
394
+ this.updateRangesArray();
395
+ }
396
+ get isInlineMode() {
397
+ return this.inline === true || this.inline === 'always' ||
398
+ (this.inline === 'auto' && typeof window !== 'undefined' && window.matchMedia('(min-width: 768px)').matches);
399
+ }
400
+ get isCalendarVisible() {
401
+ return this.isInlineMode || this.isCalendarOpen;
402
+ }
403
+ get displayValue() {
404
+ if (this.mode === 'single' && this.selectedDate) {
405
+ return this.selectedDate.toLocaleString(this.locale, {
406
+ year: 'numeric', month: 'short', day: '2-digit',
407
+ hour: this.showTime ? '2-digit' : undefined,
408
+ minute: this.showTime ? '2-digit' : undefined
409
+ });
137
410
  }
138
- else {
139
- this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {
140
- const start = this._normalizeDate(dates[0]);
141
- const end = this._normalizeDate(dates[1]);
142
- if (start && end)
143
- acc[key] = [start, end];
144
- return acc;
145
- }, {});
411
+ else if (this.mode === 'range' && this.startDate && this.endDate) {
412
+ const start = this.startDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
413
+ const end = this.endDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
414
+ return `${start} - ${end}`;
146
415
  }
147
- this.updateRangesArray();
416
+ else if (this.mode === 'multiple' && this.selectedDates.length > 0) {
417
+ return `${this.selectedDates.length} dates selected`;
418
+ }
419
+ return '';
420
+ }
421
+ onDocumentClick(event) {
422
+ if (!this.isInlineMode && this.isCalendarOpen && !this.elementRef.nativeElement.contains(event.target)) {
423
+ this.isCalendarOpen = false;
424
+ }
425
+ }
426
+ writeValue(val) {
427
+ this._internalValue = val;
428
+ this.initializeValue(val);
429
+ this.generateCalendar();
430
+ }
431
+ registerOnChange(fn) {
432
+ this.onChange = fn;
433
+ }
434
+ registerOnTouched(fn) {
435
+ this.onTouched = fn;
436
+ }
437
+ setDisabledState(isDisabled) {
438
+ this.disabled = isDisabled;
439
+ }
440
+ emitValue(val) {
441
+ this._internalValue = val;
442
+ this.valueChange.emit(val);
443
+ this.onChange(val);
444
+ this.onTouched();
445
+ // Auto-close popover when a selection is complete
446
+ if (!this.isInlineMode && val !== null) {
447
+ if (this.mode === 'single' || (this.mode === 'range' && this.startDate && this.endDate)) {
448
+ this.isCalendarOpen = false;
449
+ }
450
+ }
451
+ }
452
+ toggleCalendar() {
453
+ if (this.disabled || this.isInlineMode)
454
+ return;
455
+ this.isCalendarOpen = !this.isCalendarOpen;
456
+ }
457
+ clearValue(event) {
458
+ if (event)
459
+ event.stopPropagation();
460
+ if (this.disabled)
461
+ return;
462
+ this.selectedDate = null;
463
+ this.selectedDates = [];
464
+ this.startDate = null;
465
+ this.endDate = null;
466
+ this.hoveredDate = null;
467
+ this.isCalendarOpen = false;
468
+ this.emitValue(null);
469
+ this.action.emit({ type: 'clear', payload: null });
470
+ // Reset view to today after clearing
471
+ this.currentDate = new Date();
472
+ this._currentMonth = this.currentDate.getMonth();
473
+ this._currentYear = this.currentDate.getFullYear();
474
+ this.generateCalendar();
148
475
  }
149
476
  get currentMonth() { return this._currentMonth; }
150
477
  set currentMonth(month) {
478
+ if (this.disabled)
479
+ return;
151
480
  if (this._currentMonth !== month) {
152
481
  this._currentMonth = month;
153
482
  this.currentDate.setMonth(month);
154
- this.generateCalendar();
483
+ this.generateCalendar(true);
155
484
  }
156
485
  }
157
486
  get currentYear() { return this._currentYear; }
158
487
  set currentYear(year) {
488
+ if (this.disabled)
489
+ return;
159
490
  if (this._currentYear !== year) {
160
491
  this._currentYear = year;
161
492
  this.currentDate.setFullYear(year);
162
- this.generateCalendar();
493
+ this.generateCalendar(true);
163
494
  }
164
495
  }
165
496
  ngOnInit() {
166
- if (this._locale === 'en-US') {
497
+ if (this._locale === 'en-US' && typeof navigator !== 'undefined') {
167
498
  this._locale = navigator.language;
168
499
  }
169
500
  this.today.setHours(0, 0, 0, 0);
170
501
  this.generateLocaleData();
171
502
  this.generateTimeOptions();
172
- if (this.showTime && !this.value) {
503
+ if (this.showTime && !this._internalValue) {
173
504
  const now = new Date();
174
505
  this.currentHour = now.getHours();
175
506
  this.currentMinute = Math.floor(now.getMinutes() / this.minuteInterval) * this.minuteInterval;
@@ -179,8 +510,8 @@ class NgxsmkDatepickerComponent {
179
510
  }
180
511
  this.update12HourState(this.currentHour);
181
512
  }
182
- if (this.value) {
183
- this.initializeValue(this.value);
513
+ if (this._internalValue) {
514
+ this.initializeValue(this._internalValue);
184
515
  }
185
516
  else if (this._startAtDate) {
186
517
  this.initializeValue(null);
@@ -198,11 +529,14 @@ class NgxsmkDatepickerComponent {
198
529
  this.onTimeChange();
199
530
  }
200
531
  if (changes['value'] && changes['value'].currentValue !== changes['value'].previousValue) {
201
- this.initializeValue(changes['value'].currentValue);
532
+ this.writeValue(changes['value'].currentValue);
533
+ }
534
+ // Rerun calendar generation if provider changes to refresh disabled states
535
+ if (changes['holidayProvider'] || changes['disableHolidays']) {
202
536
  this.generateCalendar();
203
537
  }
204
538
  if (changes['startAt']) {
205
- if (!this.value && this._startAtDate) {
539
+ if (!this._internalValue && this._startAtDate) {
206
540
  this.currentDate = new Date(this._startAtDate);
207
541
  this._currentMonth = this.currentDate.getMonth();
208
542
  this._currentYear = this.currentDate.getFullYear();
@@ -211,14 +545,12 @@ class NgxsmkDatepickerComponent {
211
545
  }
212
546
  }
213
547
  get24Hour(displayHour, isPm) {
214
- if (isPm) {
215
- return displayHour === 12 ? 12 : displayHour + 12;
216
- }
217
- return displayHour === 12 ? 0 : displayHour;
548
+ return get24Hour(displayHour, isPm);
218
549
  }
219
550
  update12HourState(fullHour) {
220
- this.isPm = fullHour >= 12;
221
- this.currentDisplayHour = fullHour % 12 || 12;
551
+ const state = update12HourState(fullHour);
552
+ this.isPm = state.isPm;
553
+ this.currentDisplayHour = state.displayHour;
222
554
  }
223
555
  applyCurrentTime(date) {
224
556
  this.currentHour = this.get24Hour(this.currentDisplayHour, this.isPm);
@@ -227,6 +559,10 @@ class NgxsmkDatepickerComponent {
227
559
  }
228
560
  initializeValue(value) {
229
561
  let initialDate = null;
562
+ this.selectedDate = null;
563
+ this.startDate = null;
564
+ this.endDate = null;
565
+ this.selectedDates = [];
230
566
  if (value) {
231
567
  if (this.mode === 'single' && value instanceof Date) {
232
568
  this.selectedDate = this._normalizeDate(value);
@@ -237,11 +573,10 @@ class NgxsmkDatepickerComponent {
237
573
  this.endDate = this._normalizeDate(value.end);
238
574
  initialDate = this.startDate;
239
575
  }
240
- }
241
- else {
242
- this.selectedDate = null;
243
- this.startDate = null;
244
- this.endDate = null;
576
+ else if (this.mode === 'multiple' && Array.isArray(value)) {
577
+ this.selectedDates = value.map(d => this._normalizeDate(d)).filter((d) => d !== null);
578
+ initialDate = this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
579
+ }
245
580
  }
246
581
  const viewCenterDate = initialDate || this._startAtDate || new Date();
247
582
  if (viewCenterDate) {
@@ -255,103 +590,116 @@ class NgxsmkDatepickerComponent {
255
590
  }
256
591
  }
257
592
  _normalizeDate(date) {
258
- if (!date)
259
- return null;
260
- const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date);
261
- if (isNaN(d.getTime()))
262
- return null;
263
- return d;
593
+ return normalizeDate(date);
264
594
  }
265
595
  generateTimeOptions() {
266
- this.hourOptions = Array.from({ length: 12 }).map((_, i) => ({
267
- label: (i + 1).toString().padStart(2, '0'),
268
- value: i + 1,
269
- }));
270
- this.minuteOptions = [];
271
- for (let i = 0; i < 60; i += this.minuteInterval) {
272
- this.minuteOptions.push({
273
- label: i.toString().padStart(2, '0'),
274
- value: i,
275
- });
276
- }
596
+ const { hourOptions, minuteOptions } = generateTimeOptions(this.minuteInterval);
597
+ this.hourOptions = hourOptions;
598
+ this.minuteOptions = minuteOptions;
277
599
  }
278
600
  generateLocaleData() {
279
601
  const year = new Date().getFullYear();
280
- this.monthOptions = Array.from({ length: 12 }).map((_, i) => ({
281
- label: new Date(year, i, 1).toLocaleDateString(this.locale, { month: 'long' }),
282
- value: i,
283
- }));
284
- try {
285
- this.firstDayOfWeek = (new Intl.Locale(this.locale).weekInfo?.firstDay || 0) % 7;
286
- }
287
- catch (e) {
288
- this.firstDayOfWeek = 0;
289
- }
290
- const day = new Date(year, 0, 7 + this.firstDayOfWeek);
291
- this.weekDays = Array.from({ length: 7 }).map(() => {
292
- const weekDay = new Date(day).toLocaleDateString(this.locale, { weekday: 'short' });
293
- day.setDate(day.getDate() + 1);
294
- return weekDay;
295
- });
602
+ this.monthOptions = generateMonthOptions(this.locale, year);
603
+ this.firstDayOfWeek = getFirstDayOfWeek(this.locale);
604
+ this.weekDays = generateWeekDays(this.locale, this.firstDayOfWeek);
296
605
  }
297
606
  updateRangesArray() {
298
607
  this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({ key, value })) : [];
299
608
  }
300
609
  selectRange(range) {
610
+ if (this.disabled)
611
+ return;
301
612
  this.startDate = this.applyCurrentTime(range[0]);
302
613
  this.endDate = this.applyCurrentTime(range[1]);
303
614
  if (this.startDate && this.endDate) {
304
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
615
+ this.emitValue({ start: this.startDate, end: this.endDate });
305
616
  }
306
617
  this.currentDate = new Date(this.startDate);
307
618
  this.initializeValue({ start: this.startDate, end: this.endDate });
308
619
  this.generateCalendar();
620
+ this.action.emit({ type: 'rangeSelected', payload: { start: this.startDate, end: this.endDate, key: this.rangesArray.find(r => r.value === range)?.key } });
621
+ }
622
+ // NEW: Check if a date is a holiday
623
+ isHoliday(date) {
624
+ if (!date || !this.holidayProvider)
625
+ return false;
626
+ const dateOnly = getStartOfDay(date);
627
+ return this.holidayProvider.isHoliday(dateOnly);
628
+ }
629
+ // NEW: Get holiday label
630
+ getHolidayLabel(date) {
631
+ if (!date || !this.holidayProvider || !this.isHoliday(date))
632
+ return null;
633
+ return this.holidayProvider.getHolidayLabel ? this.holidayProvider.getHolidayLabel(getStartOfDay(date)) : 'Holiday';
309
634
  }
310
635
  isDateDisabled(date) {
311
636
  if (!date)
312
637
  return false;
313
- const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
638
+ const dateOnly = getStartOfDay(date);
639
+ // 1. Check holiday provider for disabling
640
+ if (this.holidayProvider && this.disableHolidays && this.holidayProvider.isHoliday(dateOnly)) {
641
+ return true;
642
+ }
643
+ // 2. Check min/max date
314
644
  if (this._minDate) {
315
- const minDateOnly = new Date(this._minDate.getFullYear(), this._minDate.getMonth(), this._minDate.getDate());
316
- if (dateOnly < minDateOnly)
645
+ const minDateOnly = getStartOfDay(this._minDate);
646
+ if (dateOnly.getTime() < minDateOnly.getTime())
317
647
  return true;
318
648
  }
319
649
  if (this._maxDate) {
320
- const maxDateOnly = new Date(this._maxDate.getFullYear(), this._maxDate.getMonth(), this._maxDate.getDate());
321
- if (dateOnly > maxDateOnly)
650
+ const maxDateOnly = getStartOfDay(this._maxDate);
651
+ if (dateOnly.getTime() > maxDateOnly.getTime())
322
652
  return true;
323
653
  }
654
+ // 3. Check custom invalid date function
324
655
  return this.isInvalidDate(date);
325
656
  }
657
+ isMultipleSelected(d) {
658
+ if (!d || this.mode !== 'multiple')
659
+ return false;
660
+ const dTime = getStartOfDay(d).getTime();
661
+ return this.selectedDates.some(selected => getStartOfDay(selected).getTime() === dTime);
662
+ }
326
663
  onTimeChange() {
664
+ if (this.disabled)
665
+ return;
327
666
  if (this.mode === 'single' && this.selectedDate) {
328
667
  this.selectedDate = this.applyCurrentTime(this.selectedDate);
329
- this.valueChange.emit(this.selectedDate);
668
+ this.emitValue(this.selectedDate);
330
669
  }
331
670
  else if (this.mode === 'range' && this.startDate && this.endDate) {
332
671
  this.startDate = this.applyCurrentTime(this.startDate);
333
672
  this.endDate = this.applyCurrentTime(this.endDate);
334
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
673
+ this.emitValue({ start: this.startDate, end: this.endDate });
335
674
  }
336
675
  else if (this.mode === 'range' && this.startDate && !this.endDate) {
337
676
  this.startDate = this.applyCurrentTime(this.startDate);
338
677
  }
678
+ else if (this.mode === 'multiple') {
679
+ this.selectedDates = this.selectedDates.map(date => {
680
+ const newDate = getStartOfDay(date);
681
+ return this.applyCurrentTime(newDate);
682
+ });
683
+ this.emitValue([...this.selectedDates]);
684
+ }
685
+ this.action.emit({ type: 'timeChanged', payload: { hour: this.currentHour, minute: this.currentMinute } });
339
686
  }
340
687
  onDateClick(day) {
341
- if (!day || this.isDateDisabled(day))
688
+ if (!day || this.isDateDisabled(day) || this.disabled)
342
689
  return;
690
+ const dateToToggle = getStartOfDay(day);
343
691
  if (this.mode === 'single') {
344
692
  this.selectedDate = this.applyCurrentTime(day);
345
- this.valueChange.emit(this.selectedDate);
693
+ this.emitValue(this.selectedDate);
346
694
  }
347
- else {
695
+ else if (this.mode === 'range') {
348
696
  if (!this.startDate || (this.startDate && this.endDate)) {
349
697
  this.startDate = this.applyCurrentTime(day);
350
698
  this.endDate = null;
351
699
  }
352
700
  else if (day >= this.startDate) {
353
701
  this.endDate = this.applyCurrentTime(day);
354
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
702
+ this.emitValue({ start: this.startDate, end: this.endDate });
355
703
  }
356
704
  else {
357
705
  this.startDate = this.applyCurrentTime(day);
@@ -359,14 +707,33 @@ class NgxsmkDatepickerComponent {
359
707
  }
360
708
  this.hoveredDate = null;
361
709
  }
362
- if (this.mode === 'single' && this.selectedDate) {
363
- this.update12HourState(this.selectedDate.getHours());
364
- this.currentMinute = this.selectedDate.getMinutes();
710
+ else if (this.mode === 'multiple') {
711
+ const existingIndex = this.selectedDates.findIndex(d => this.isSameDay(d, dateToToggle));
712
+ if (existingIndex > -1) {
713
+ this.selectedDates.splice(existingIndex, 1);
714
+ }
715
+ else {
716
+ const dateWithTime = this.applyCurrentTime(dateToToggle);
717
+ this.selectedDates.push(dateWithTime);
718
+ this.selectedDates.sort((a, b) => a.getTime() - b.getTime());
719
+ }
720
+ this.emitValue([...this.selectedDates]);
365
721
  }
366
- else if (this.mode === 'range' && this.startDate) {
367
- this.update12HourState(this.startDate.getHours());
368
- this.currentMinute = this.startDate.getMinutes();
722
+ const dateToSync = this.mode === 'single' ? this.selectedDate :
723
+ this.mode === 'range' ? this.startDate :
724
+ this.mode === 'multiple' && this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
725
+ if (dateToSync) {
726
+ this.update12HourState(dateToSync.getHours());
727
+ this.currentMinute = dateToSync.getMinutes();
369
728
  }
729
+ this.action.emit({
730
+ type: 'dateSelected',
731
+ payload: {
732
+ mode: this.mode,
733
+ value: this._internalValue,
734
+ date: day
735
+ }
736
+ });
370
737
  }
371
738
  onDateHover(day) {
372
739
  if (this.mode === 'range' && this.startDate && !this.endDate && day) {
@@ -376,12 +743,12 @@ class NgxsmkDatepickerComponent {
376
743
  isPreviewInRange(day) {
377
744
  if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day)
378
745
  return false;
379
- const start = this.startDate.getTime();
380
- const end = this.hoveredDate.getTime();
381
- const time = day.getTime();
746
+ const start = getStartOfDay(this.startDate).getTime();
747
+ const end = getStartOfDay(this.hoveredDate).getTime();
748
+ const time = getStartOfDay(day).getTime();
382
749
  return time > Math.min(start, end) && time < Math.max(start, end);
383
750
  }
384
- generateCalendar() {
751
+ generateCalendar(resetAnimation = true) {
385
752
  this.daysInMonth = [];
386
753
  const year = this.currentDate.getFullYear();
387
754
  const month = this.currentDate.getMonth();
@@ -398,206 +765,316 @@ class NgxsmkDatepickerComponent {
398
765
  for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
399
766
  this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));
400
767
  }
768
+ if (resetAnimation) {
769
+ this.animateForward = false;
770
+ this.animateBackward = false;
771
+ }
772
+ this.action.emit({
773
+ type: 'calendarGenerated',
774
+ payload: {
775
+ month: month,
776
+ year: year,
777
+ days: this.daysInMonth.filter(d => d !== null)
778
+ }
779
+ });
401
780
  }
402
781
  generateDropdownOptions() {
403
- const startYear = this._currentYear - 10;
404
- const endYear = this._currentYear + 10;
405
- this.yearOptions = [];
406
- for (let i = startYear; i <= endYear; i++) {
407
- this.yearOptions.push({ label: `${i}`, value: i });
408
- }
782
+ this.yearOptions = generateYearOptions(this._currentYear);
409
783
  }
410
784
  changeMonth(delta) {
411
- this.currentDate.setMonth(this.currentDate.getMonth() + delta);
412
- this.generateCalendar();
785
+ if (this.disabled)
786
+ return;
787
+ // 1. Set the animation class (triggers slide-out)
788
+ if (delta > 0) {
789
+ this.animateForward = true;
790
+ this.animateBackward = false;
791
+ }
792
+ else {
793
+ this.animateBackward = true;
794
+ this.animateForward = false;
795
+ }
796
+ const newDate = addMonths(this.currentDate, delta);
797
+ // 2. Wait for the slide-out transition to complete (300ms)
798
+ setTimeout(() => {
799
+ // 3. Update the data
800
+ this.currentDate = newDate;
801
+ this._currentMonth = newDate.getMonth();
802
+ this._currentYear = newDate.getFullYear();
803
+ // Generate new calendar view but tell it *not* to reset animation flags yet.
804
+ this.generateCalendar(false);
805
+ // 4. Reset the animation flags to false (triggers slide-in of the new content)
806
+ this.animateForward = false;
807
+ this.animateBackward = false;
808
+ }, 300); // Wait time should match the CSS transition duration (0.3s)
809
+ this.action.emit({ type: 'monthChanged', payload: { delta: delta } });
413
810
  }
414
811
  isSameDay(d1, d2) {
415
- if (!d1 || !d2)
416
- return false;
417
- return (d1.getFullYear() === d2.getFullYear() &&
418
- d1.getMonth() === d2.getMonth() &&
419
- d1.getDate() === d2.getDate());
812
+ return this.dateComparator(d1, d2);
420
813
  }
421
814
  isInRange(d) {
422
815
  if (!d || !this.startDate || !this.endDate)
423
816
  return false;
424
- const dTime = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
425
- const startDayTime = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate()).getTime();
426
- const endDayTime = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate()).getTime();
817
+ const dTime = getStartOfDay(d).getTime();
818
+ const startDayTime = getStartOfDay(this.startDate).getTime();
819
+ const endDayTime = getStartOfDay(this.endDate).getTime();
427
820
  const startTime = Math.min(startDayTime, endDayTime);
428
821
  const endTime = Math.max(startDayTime, endDayTime);
429
822
  return dTime > startTime && dTime < endTime;
430
823
  }
824
+ ngOnDestroy() {
825
+ // Clean up any subscriptions or timers if needed
826
+ // Currently no cleanup required, but method is here for future optimizations
827
+ }
431
828
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
432
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: NgxsmkDatepickerComponent, isStandalone: true, selector: "ngxsmk-datepicker", inputs: { mode: "mode", isInvalidDate: "isInvalidDate", showRanges: "showRanges", showTime: "showTime", minuteInterval: "minuteInterval", value: "value", startAt: "startAt", locale: "locale", theme: "theme", minDate: "minDate", maxDate: "maxDate", ranges: "ranges" }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.dark-theme": "this.isDarkMode" } }, usesOnChanges: true, ngImport: i0, template: `
433
- <div class="ngxsmk-datepicker-container">
434
- @if (showRanges && rangesArray.length > 0 && mode === 'range') {
435
- <div class="ngxsmk-ranges-container">
436
- <ul>
437
- @for (range of rangesArray; track range.key) {
438
- <li (click)="selectRange(range.value)">{{ range.key }}</li>
439
- }
440
- </ul>
829
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: NgxsmkDatepickerComponent, isStandalone: true, selector: "ngxsmk-datepicker", inputs: { mode: "mode", isInvalidDate: "isInvalidDate", showRanges: "showRanges", showTime: "showTime", minuteInterval: "minuteInterval", holidayProvider: "holidayProvider", disableHolidays: "disableHolidays", placeholder: "placeholder", inline: "inline", startAt: "startAt", locale: "locale", theme: "theme", disabledState: "disabledState", minDate: "minDate", maxDate: "maxDate", ranges: "ranges" }, outputs: { valueChange: "valueChange", action: "action" }, host: { listeners: { "document:click": "onDocumentClick($event)" }, properties: { "class.dark-theme": "this.isDarkMode" } }, providers: [{
830
+ provide: NG_VALUE_ACCESSOR,
831
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
832
+ multi: true
833
+ }], usesOnChanges: true, ngImport: i0, template: `
834
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
835
+ @if (!isInlineMode) {
836
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
837
+ <input type="text"
838
+ [value]="displayValue"
839
+ [placeholder]="placeholder"
840
+ readonly
841
+ [disabled]="disabled"
842
+ class="ngxsmk-display-input">
843
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
844
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 368L144 144M368 144L144 368"/></svg>
845
+ </button>
441
846
  </div>
442
847
  }
443
- <div class="ngxsmk-calendar-container">
444
- <div class="ngxsmk-header">
445
- <div class="ngxsmk-month-year-selects">
446
- <app-custom-select class="month-select" [options]="monthOptions"
447
- [(value)]="currentMonth"></app-custom-select>
448
- <app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear"></app-custom-select>
449
- </div>
450
- <div class="ngxsmk-nav-buttons">
451
- <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)">
452
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
453
- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
454
- d="M328 112L184 256l144 144"/>
455
- </svg>
456
- </button>
457
- <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)">
458
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
459
- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
460
- d="M184 112l144 144-144 144"/>
461
- </svg>
462
- </button>
463
- </div>
464
- </div>
465
- <div class="ngxsmk-days-grid-wrapper">
466
- <div class="ngxsmk-days-grid">
467
- @for (day of weekDays; track day) {
468
- <div class="ngxsmk-day-name">{{ day }}</div>
469
- }
470
- @for (day of daysInMonth; track $index) {
471
- <div class="ngxsmk-day-cell"
472
- [class.empty]="!day" [class.disabled]="isDateDisabled(day)" [class.today]="isSameDay(day, today)"
473
- [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
474
- [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
475
- [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
476
- [class.in-range]="mode === 'range' && isInRange(day)"
477
- [class.preview-range]="isPreviewInRange(day)"
478
- (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
479
- @if (day) {
480
- <div class="ngxsmk-day-number">{{ day | date : 'd' }}</div>
481
- }
848
+
849
+ @if (isCalendarVisible) {
850
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
851
+ <div class="ngxsmk-datepicker-container">
852
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
853
+ <div class="ngxsmk-ranges-container">
854
+ <ul>
855
+ @for (range of rangesArray; track range.key) {
856
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
857
+ }
858
+ </ul>
482
859
  </div>
483
860
  }
484
- </div>
485
- </div>
861
+ <div class="ngxsmk-calendar-container">
862
+ <div class="ngxsmk-header">
863
+ <div class="ngxsmk-month-year-selects">
864
+ <ngxsmk-custom-select class="month-select" [options]="monthOptions"
865
+ [(value)]="currentMonth" [disabled]="disabled"></ngxsmk-custom-select>
866
+ <ngxsmk-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></ngxsmk-custom-select>
867
+ </div>
868
+ <div class="ngxsmk-nav-buttons">
869
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled">
870
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
871
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
872
+ d="M328 112L184 256l144 144"/>
873
+ </svg>
874
+ </button>
875
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
876
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
877
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
878
+ d="M184 112l144 144-144 144"/>
879
+ </svg>
880
+ </button>
881
+ </div>
882
+ </div>
883
+ <div class="ngxsmk-days-grid-wrapper">
884
+ <div class="ngxsmk-days-grid"
885
+ [class.animate-forward]="animateForward"
886
+ [class.animate-backward]="animateBackward">
887
+ @for (day of weekDays; track day) {
888
+ <div class="ngxsmk-day-name">{{ day }}</div>
889
+ }
890
+ @for (day of daysInMonth; track $index) {
891
+ <div class="ngxsmk-day-cell"
892
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
893
+ [class.today]="isSameDay(day, today)"
894
+ [class.holiday]="isHoliday(day)"
895
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
896
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
897
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
898
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
899
+ [class.in-range]="mode === 'range' && isInRange(day)"
900
+ [class.preview-range]="isPreviewInRange(day)"
901
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
902
+ @if (day) {
903
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
904
+ }
905
+ </div>
906
+ }
907
+ </div>
908
+ </div>
486
909
 
487
- @if (showTime) {
488
- <div class="ngxsmk-time-selection">
489
- <span class="ngxsmk-time-label">Time:</span>
490
- <app-custom-select
491
- class="hour-select"
492
- [options]="hourOptions"
493
- [(value)]="currentDisplayHour"
494
- (valueChange)="onTimeChange()"
495
- ></app-custom-select>
496
- <span class="ngxsmk-time-separator">:</span>
497
- <app-custom-select
498
- class="minute-select"
499
- [options]="minuteOptions"
500
- [(value)]="currentMinute"
501
- (valueChange)="onTimeChange()"
502
- ></app-custom-select>
503
- <app-custom-select
504
- class="ampm-select"
505
- [options]="ampmOptions"
506
- [(value)]="isPm"
507
- (valueChange)="onTimeChange()"
508
- ></app-custom-select>
910
+ @if (showTime) {
911
+ <div class="ngxsmk-time-selection">
912
+ <span class="ngxsmk-time-label">Time:</span>
913
+ <ngxsmk-custom-select
914
+ class="hour-select"
915
+ [options]="hourOptions"
916
+ [(value)]="currentDisplayHour"
917
+ (valueChange)="onTimeChange()"
918
+ [disabled]="disabled"
919
+ ></ngxsmk-custom-select>
920
+ <span class="ngxsmk-time-separator">:</span>
921
+ <ngxsmk-custom-select
922
+ class="minute-select"
923
+ [options]="minuteOptions"
924
+ [(value)]="currentMinute"
925
+ (valueChange)="onTimeChange()"
926
+ [disabled]="disabled"
927
+ ></ngxsmk-custom-select>
928
+ <ngxsmk-custom-select
929
+ class="ampm-select"
930
+ [options]="ampmOptions"
931
+ [(value)]="isPm"
932
+ (valueChange)="onTimeChange()"
933
+ [disabled]="disabled"
934
+ ></ngxsmk-custom-select>
935
+ </div>
936
+ }
937
+
938
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
939
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
940
+ Clear
941
+ </button>
942
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
943
+ Close
944
+ </button>
945
+ </div>
946
+ </div>
509
947
  </div>
510
- }
511
-
512
- </div>
948
+ </div>
949
+ }
513
950
  </div>
514
- `, isInline: true, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.ngxsmk-datepicker-container{display:flex;flex-direction:column}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:12px;background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:12px;border-right:none;border-bottom:1px solid var(--datepicker-border-color);background:var(--datepicker-hover-background);border-radius:10px 10px 0 0}.ngxsmk-ranges-container ul{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:6px 10px;margin-bottom:0;font-size:.85rem;border:1px solid var(--datepicker-border-color);transition:background-color .15s ease}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;position:relative;z-index:2;gap:4px}.ngxsmk-month-year-selects{display:flex;gap:4px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 100px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 75px}.ngxsmk-nav-buttons{display:flex}.ngxsmk-nav-button{padding:6px}.ngxsmk-nav-button svg{width:16px;height:16px}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-size:.75rem;padding:6px 0}.ngxsmk-day-cell{height:32px}.ngxsmk-day-number{width:30px;height:30px;font-size:.9rem}.ngxsmk-time-selection{display:flex;align-content:center;gap:5px;flex-wrap:wrap;margin-top:12px;padding-top:8px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 55px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 65px}.ngxsmk-time-separator{font-size:1rem}@media (min-width: 600px){.ngxsmk-datepicker-container{display:flex;flex-direction:row}.ngxsmk-calendar-container{padding:16px;box-shadow:none;width:auto}.ngxsmk-ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);border-bottom:none;background:var(--datepicker-background);border-radius:10px 0 0 10px}.ngxsmk-ranges-container ul{flex-direction:column;justify-content:flex-start;gap:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border:none;font-size:1rem}.ngxsmk-header{margin-bottom:12px;gap:5px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.ngxsmk-nav-button{padding:8px}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:.8rem;padding:8px 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:1rem}.ngxsmk-time-selection{margin-top:16px;padding-top:12px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}}.ngxsmk-nav-button:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button{background:none;border:none;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-day-cell{position:relative;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-number{display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);position:relative;z-index:1}.ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number{background-color:var(--datepicker-hover-background);color:var(--datepicker-primary-color)}.ngxsmk-day-cell.start-date .ngxsmk-day-number,.ngxsmk-day-cell.end-date .ngxsmk-day-number,.ngxsmk-day-cell.selected .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.in-range,.ngxsmk-day-cell.start-date,.ngxsmk-day-cell.end-date,.ngxsmk-day-cell.preview-range{background-color:var(--datepicker-range-background)}.ngxsmk-day-cell.start-date{border-top-left-radius:100%;border-bottom-left-radius:100%}.ngxsmk-day-cell.end-date{border-top-right-radius:100%;border-bottom-right-radius:100%}.ngxsmk-day-cell.start-date.end-date{border-radius:50px}.ngxsmk-day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.ngxsmk-day-cell.today .ngxsmk-day-number{border:1px solid var(--datepicker-primary-color)}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-time-label{font-size:.9rem;color:var(--datepicker-subtle-text-color);margin-right:4px}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: CustomSelectComponent, selector: "app-custom-select", inputs: ["options", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
951
+ `, isInline: true, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0;display:inline-block;position:relative}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.ngxsmk-datepicker-wrapper{position:relative}.ngxsmk-input-group{display:flex;align-items:center;cursor:pointer;width:100%;min-width:150px;border:1px solid var(--datepicker-border-color, #ccc);border-radius:4px;background:var(--datepicker-background);transition:border-color .15s ease}.ngxsmk-input-group:hover:not(.disabled){border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.disabled{cursor:not-allowed;opacity:.7}.ngxsmk-display-input{flex-grow:1;padding:6px 8px;font-size:14px;color:var(--datepicker-text-color, #333);background:transparent;border:none;outline:none;cursor:pointer}.ngxsmk-display-input:disabled{background:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed}.ngxsmk-clear-button{background:none;border:none;padding:0 8px;cursor:pointer;color:var(--datepicker-subtle-text-color);line-height:1}.ngxsmk-clear-button svg{width:14px;height:14px}.ngxsmk-clear-button:hover{color:var(--datepicker-text-color)}.ngxsmk-popover-container{position:absolute;top:100%;left:0;z-index:10000;margin-top:8px}.ngxsmk-popover-container.ngxsmk-inline-container{position:static;margin-top:0}.ngxsmk-datepicker-wrapper.ngxsmk-inline-mode{display:block}.ngxsmk-datepicker-wrapper.ngxsmk-inline-mode .ngxsmk-datepicker-container{box-shadow:none;border:1px solid var(--datepicker-border-color)}.ngxsmk-footer{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:8px;border-top:1px solid var(--datepicker-border-color)}.ngxsmk-clear-button-footer,.ngxsmk-close-button{padding:6px 12px;border-radius:6px;font-size:.9rem;cursor:pointer;transition:background-color .2s;border:1px solid var(--datepicker-border-color)}.ngxsmk-clear-button-footer{background:none;color:var(--datepicker-subtle-text-color)}.ngxsmk-close-button{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast);border-color:var(--datepicker-primary-color)}.ngxsmk-close-button:hover:not(:disabled){opacity:.9}.ngxsmk-clear-button-footer:hover:not(:disabled){background-color:var(--datepicker-hover-background)}.ngxsmk-datepicker-container{display:flex;flex-direction:column;width:100%}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:12px;background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:12px;border-right:none;border-bottom:1px solid var(--datepicker-border-color);background:var(--datepicker-hover-background);border-radius:10px 10px 0 0}.ngxsmk-ranges-container ul{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:6px 10px;margin-bottom:0;font-size:.85rem;border:1px solid var(--datepicker-border-color);border-radius:6px;cursor:pointer;transition:background-color .15s ease;flex-shrink:0}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-ranges-container li.disabled{cursor:not-allowed;opacity:.5;background-color:transparent!important;color:var(--datepicker-subtle-text-color, #9ca3af)}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;position:relative;z-index:2;gap:4px}.ngxsmk-month-year-selects{display:flex;gap:4px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 100px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 75px}.ngxsmk-nav-buttons{display:flex}.ngxsmk-nav-button{padding:6px;background:none;border:none;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-nav-button:hover:not(:disabled){background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button:disabled{cursor:not-allowed;opacity:.5}.ngxsmk-nav-button svg{width:16px;height:16px}.ngxsmk-days-grid-wrapper{overflow-x:hidden}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0;transition:transform .3s ease-out,opacity .15s ease-out .15s}.ngxsmk-days-grid.animate-forward{transform:translate(-100%);opacity:0}.ngxsmk-days-grid.animate-backward{transform:translate(100%);opacity:0}.ngxsmk-day-name{font-size:.75rem;padding:6px 0;color:var(--datepicker-subtle-text-color);font-weight:600}.ngxsmk-day-cell{height:32px;position:relative;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-cell.holiday .ngxsmk-day-number{color:var(--datepicker-primary-color);text-decoration:underline dotted}.ngxsmk-day-number{width:30px;height:30px;display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);font-size:.9rem;position:relative;z-index:1}.ngxsmk-time-selection{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin-top:12px;padding-top:8px;border-top:1px solid var(--datepicker-border-color)}.ngxsmk-time-label{font-size:.9rem;color:var(--datepicker-subtle-text-color);margin-right:4px}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}.ngxsmk-time-selection app-custom-select{--custom-select-width: 55px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 65px}.ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number{background-color:var(--datepicker-hover-background);color:var(--datepicker-primary-color)}.ngxsmk-day-cell.start-date .ngxsmk-day-number,.ngxsmk-day-cell.end-date .ngxsmk-day-number,.ngxsmk-day-cell.selected .ngxsmk-day-number,.ngxsmk-day-cell.multiple-selected .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.multiple-selected .ngxsmk-day-number{border:1px dashed var(--datepicker-primary-contrast)}.ngxsmk-day-cell.multiple-selected:hover .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.in-range,.ngxsmk-day-cell.start-date,.ngxsmk-day-cell.end-date,.ngxsmk-day-cell.preview-range{background-color:var(--datepicker-range-background)}.ngxsmk-day-cell.start-date{border-top-left-radius:100%;border-bottom-left-radius:100%}.ngxsmk-day-cell.end-date{border-top-right-radius:100%;border-bottom-right-radius:100%}.ngxsmk-day-cell.start-date.end-date{border-radius:50px}.ngxsmk-day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.ngxsmk-day-cell.today .ngxsmk-day-number{border:1px solid var(--datepicker-primary-color)}@media (min-width: 600px){.ngxsmk-datepicker-container{display:flex;flex-direction:row}.ngxsmk-calendar-container{padding:16px;box-shadow:0 4px 10px #0000001a;width:auto;border-radius:0 10px 10px 0}.ngxsmk-ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);border-bottom:none;background:var(--datepicker-background);border-radius:10px 0 0 10px}.ngxsmk-ranges-container ul{flex-direction:column;justify-content:flex-start;gap:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border:none;font-size:1rem}.ngxsmk-header{margin-bottom:12px;gap:5px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.ngxsmk-nav-button{padding:8px}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:.8rem;padding:8px 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:1rem}.ngxsmk-time-selection{margin-top:16px;padding-top:12px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: CustomSelectComponent, selector: "ngxsmk-custom-select", inputs: ["options", "value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: i1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
515
952
  }
516
953
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, decorators: [{
517
954
  type: Component,
518
- args: [{ selector: 'ngxsmk-datepicker', standalone: true, imports: [CommonModule, FormsModule, CustomSelectComponent], template: `
519
- <div class="ngxsmk-datepicker-container">
520
- @if (showRanges && rangesArray.length > 0 && mode === 'range') {
521
- <div class="ngxsmk-ranges-container">
522
- <ul>
523
- @for (range of rangesArray; track range.key) {
524
- <li (click)="selectRange(range.value)">{{ range.key }}</li>
525
- }
526
- </ul>
955
+ args: [{ selector: 'ngxsmk-datepicker', standalone: true, imports: [CommonModule, FormsModule, CustomSelectComponent, DatePipe, ReactiveFormsModule], providers: [{
956
+ provide: NG_VALUE_ACCESSOR,
957
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
958
+ multi: true
959
+ }], changeDetection: ChangeDetectionStrategy.OnPush, template: `
960
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
961
+ @if (!isInlineMode) {
962
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
963
+ <input type="text"
964
+ [value]="displayValue"
965
+ [placeholder]="placeholder"
966
+ readonly
967
+ [disabled]="disabled"
968
+ class="ngxsmk-display-input">
969
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
970
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M368 368L144 144M368 144L144 368"/></svg>
971
+ </button>
527
972
  </div>
528
973
  }
529
- <div class="ngxsmk-calendar-container">
530
- <div class="ngxsmk-header">
531
- <div class="ngxsmk-month-year-selects">
532
- <app-custom-select class="month-select" [options]="monthOptions"
533
- [(value)]="currentMonth"></app-custom-select>
534
- <app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear"></app-custom-select>
535
- </div>
536
- <div class="ngxsmk-nav-buttons">
537
- <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)">
538
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
539
- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
540
- d="M328 112L184 256l144 144"/>
541
- </svg>
542
- </button>
543
- <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)">
544
- <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
545
- <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
546
- d="M184 112l144 144-144 144"/>
547
- </svg>
548
- </button>
549
- </div>
550
- </div>
551
- <div class="ngxsmk-days-grid-wrapper">
552
- <div class="ngxsmk-days-grid">
553
- @for (day of weekDays; track day) {
554
- <div class="ngxsmk-day-name">{{ day }}</div>
555
- }
556
- @for (day of daysInMonth; track $index) {
557
- <div class="ngxsmk-day-cell"
558
- [class.empty]="!day" [class.disabled]="isDateDisabled(day)" [class.today]="isSameDay(day, today)"
559
- [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
560
- [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
561
- [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
562
- [class.in-range]="mode === 'range' && isInRange(day)"
563
- [class.preview-range]="isPreviewInRange(day)"
564
- (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
565
- @if (day) {
566
- <div class="ngxsmk-day-number">{{ day | date : 'd' }}</div>
567
- }
974
+
975
+ @if (isCalendarVisible) {
976
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
977
+ <div class="ngxsmk-datepicker-container">
978
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
979
+ <div class="ngxsmk-ranges-container">
980
+ <ul>
981
+ @for (range of rangesArray; track range.key) {
982
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
983
+ }
984
+ </ul>
568
985
  </div>
569
986
  }
570
- </div>
571
- </div>
987
+ <div class="ngxsmk-calendar-container">
988
+ <div class="ngxsmk-header">
989
+ <div class="ngxsmk-month-year-selects">
990
+ <ngxsmk-custom-select class="month-select" [options]="monthOptions"
991
+ [(value)]="currentMonth" [disabled]="disabled"></ngxsmk-custom-select>
992
+ <ngxsmk-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></ngxsmk-custom-select>
993
+ </div>
994
+ <div class="ngxsmk-nav-buttons">
995
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled">
996
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
997
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
998
+ d="M328 112L184 256l144 144"/>
999
+ </svg>
1000
+ </button>
1001
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
1002
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
1003
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
1004
+ d="M184 112l144 144-144 144"/>
1005
+ </svg>
1006
+ </button>
1007
+ </div>
1008
+ </div>
1009
+ <div class="ngxsmk-days-grid-wrapper">
1010
+ <div class="ngxsmk-days-grid"
1011
+ [class.animate-forward]="animateForward"
1012
+ [class.animate-backward]="animateBackward">
1013
+ @for (day of weekDays; track day) {
1014
+ <div class="ngxsmk-day-name">{{ day }}</div>
1015
+ }
1016
+ @for (day of daysInMonth; track $index) {
1017
+ <div class="ngxsmk-day-cell"
1018
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
1019
+ [class.today]="isSameDay(day, today)"
1020
+ [class.holiday]="isHoliday(day)"
1021
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
1022
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
1023
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
1024
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
1025
+ [class.in-range]="mode === 'range' && isInRange(day)"
1026
+ [class.preview-range]="isPreviewInRange(day)"
1027
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
1028
+ @if (day) {
1029
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
1030
+ }
1031
+ </div>
1032
+ }
1033
+ </div>
1034
+ </div>
572
1035
 
573
- @if (showTime) {
574
- <div class="ngxsmk-time-selection">
575
- <span class="ngxsmk-time-label">Time:</span>
576
- <app-custom-select
577
- class="hour-select"
578
- [options]="hourOptions"
579
- [(value)]="currentDisplayHour"
580
- (valueChange)="onTimeChange()"
581
- ></app-custom-select>
582
- <span class="ngxsmk-time-separator">:</span>
583
- <app-custom-select
584
- class="minute-select"
585
- [options]="minuteOptions"
586
- [(value)]="currentMinute"
587
- (valueChange)="onTimeChange()"
588
- ></app-custom-select>
589
- <app-custom-select
590
- class="ampm-select"
591
- [options]="ampmOptions"
592
- [(value)]="isPm"
593
- (valueChange)="onTimeChange()"
594
- ></app-custom-select>
1036
+ @if (showTime) {
1037
+ <div class="ngxsmk-time-selection">
1038
+ <span class="ngxsmk-time-label">Time:</span>
1039
+ <ngxsmk-custom-select
1040
+ class="hour-select"
1041
+ [options]="hourOptions"
1042
+ [(value)]="currentDisplayHour"
1043
+ (valueChange)="onTimeChange()"
1044
+ [disabled]="disabled"
1045
+ ></ngxsmk-custom-select>
1046
+ <span class="ngxsmk-time-separator">:</span>
1047
+ <ngxsmk-custom-select
1048
+ class="minute-select"
1049
+ [options]="minuteOptions"
1050
+ [(value)]="currentMinute"
1051
+ (valueChange)="onTimeChange()"
1052
+ [disabled]="disabled"
1053
+ ></ngxsmk-custom-select>
1054
+ <ngxsmk-custom-select
1055
+ class="ampm-select"
1056
+ [options]="ampmOptions"
1057
+ [(value)]="isPm"
1058
+ (valueChange)="onTimeChange()"
1059
+ [disabled]="disabled"
1060
+ ></ngxsmk-custom-select>
1061
+ </div>
1062
+ }
1063
+
1064
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
1065
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
1066
+ Clear
1067
+ </button>
1068
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
1069
+ Close
1070
+ </button>
1071
+ </div>
1072
+ </div>
595
1073
  </div>
596
- }
597
-
598
- </div>
1074
+ </div>
1075
+ }
599
1076
  </div>
600
- `, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.ngxsmk-datepicker-container{display:flex;flex-direction:column}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:12px;background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:12px;border-right:none;border-bottom:1px solid var(--datepicker-border-color);background:var(--datepicker-hover-background);border-radius:10px 10px 0 0}.ngxsmk-ranges-container ul{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:6px 10px;margin-bottom:0;font-size:.85rem;border:1px solid var(--datepicker-border-color);transition:background-color .15s ease}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;position:relative;z-index:2;gap:4px}.ngxsmk-month-year-selects{display:flex;gap:4px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 100px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 75px}.ngxsmk-nav-buttons{display:flex}.ngxsmk-nav-button{padding:6px}.ngxsmk-nav-button svg{width:16px;height:16px}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-size:.75rem;padding:6px 0}.ngxsmk-day-cell{height:32px}.ngxsmk-day-number{width:30px;height:30px;font-size:.9rem}.ngxsmk-time-selection{display:flex;align-content:center;gap:5px;flex-wrap:wrap;margin-top:12px;padding-top:8px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 55px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 65px}.ngxsmk-time-separator{font-size:1rem}@media (min-width: 600px){.ngxsmk-datepicker-container{display:flex;flex-direction:row}.ngxsmk-calendar-container{padding:16px;box-shadow:none;width:auto}.ngxsmk-ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);border-bottom:none;background:var(--datepicker-background);border-radius:10px 0 0 10px}.ngxsmk-ranges-container ul{flex-direction:column;justify-content:flex-start;gap:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border:none;font-size:1rem}.ngxsmk-header{margin-bottom:12px;gap:5px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.ngxsmk-nav-button{padding:8px}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:.8rem;padding:8px 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:1rem}.ngxsmk-time-selection{margin-top:16px;padding-top:12px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}}.ngxsmk-nav-button:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button{background:none;border:none;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-day-cell{position:relative;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-number{display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);position:relative;z-index:1}.ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number{background-color:var(--datepicker-hover-background);color:var(--datepicker-primary-color)}.ngxsmk-day-cell.start-date .ngxsmk-day-number,.ngxsmk-day-cell.end-date .ngxsmk-day-number,.ngxsmk-day-cell.selected .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.in-range,.ngxsmk-day-cell.start-date,.ngxsmk-day-cell.end-date,.ngxsmk-day-cell.preview-range{background-color:var(--datepicker-range-background)}.ngxsmk-day-cell.start-date{border-top-left-radius:100%;border-bottom-left-radius:100%}.ngxsmk-day-cell.end-date{border-top-right-radius:100%;border-bottom-right-radius:100%}.ngxsmk-day-cell.start-date.end-date{border-radius:50px}.ngxsmk-day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.ngxsmk-day-cell.today .ngxsmk-day-number{border:1px solid var(--datepicker-primary-color)}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-time-label{font-size:.9rem;color:var(--datepicker-subtle-text-color);margin-right:4px}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}\n"] }]
1077
+ `, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0;display:inline-block;position:relative}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.ngxsmk-datepicker-wrapper{position:relative}.ngxsmk-input-group{display:flex;align-items:center;cursor:pointer;width:100%;min-width:150px;border:1px solid var(--datepicker-border-color, #ccc);border-radius:4px;background:var(--datepicker-background);transition:border-color .15s ease}.ngxsmk-input-group:hover:not(.disabled){border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.disabled{cursor:not-allowed;opacity:.7}.ngxsmk-display-input{flex-grow:1;padding:6px 8px;font-size:14px;color:var(--datepicker-text-color, #333);background:transparent;border:none;outline:none;cursor:pointer}.ngxsmk-display-input:disabled{background:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed}.ngxsmk-clear-button{background:none;border:none;padding:0 8px;cursor:pointer;color:var(--datepicker-subtle-text-color);line-height:1}.ngxsmk-clear-button svg{width:14px;height:14px}.ngxsmk-clear-button:hover{color:var(--datepicker-text-color)}.ngxsmk-popover-container{position:absolute;top:100%;left:0;z-index:10000;margin-top:8px}.ngxsmk-popover-container.ngxsmk-inline-container{position:static;margin-top:0}.ngxsmk-datepicker-wrapper.ngxsmk-inline-mode{display:block}.ngxsmk-datepicker-wrapper.ngxsmk-inline-mode .ngxsmk-datepicker-container{box-shadow:none;border:1px solid var(--datepicker-border-color)}.ngxsmk-footer{display:flex;justify-content:flex-end;gap:8px;margin-top:12px;padding-top:8px;border-top:1px solid var(--datepicker-border-color)}.ngxsmk-clear-button-footer,.ngxsmk-close-button{padding:6px 12px;border-radius:6px;font-size:.9rem;cursor:pointer;transition:background-color .2s;border:1px solid var(--datepicker-border-color)}.ngxsmk-clear-button-footer{background:none;color:var(--datepicker-subtle-text-color)}.ngxsmk-close-button{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast);border-color:var(--datepicker-primary-color)}.ngxsmk-close-button:hover:not(:disabled){opacity:.9}.ngxsmk-clear-button-footer:hover:not(:disabled){background-color:var(--datepicker-hover-background)}.ngxsmk-datepicker-container{display:flex;flex-direction:column;width:100%}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:12px;background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:12px;border-right:none;border-bottom:1px solid var(--datepicker-border-color);background:var(--datepicker-hover-background);border-radius:10px 10px 0 0}.ngxsmk-ranges-container ul{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:6px 10px;margin-bottom:0;font-size:.85rem;border:1px solid var(--datepicker-border-color);border-radius:6px;cursor:pointer;transition:background-color .15s ease;flex-shrink:0}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-ranges-container li.disabled{cursor:not-allowed;opacity:.5;background-color:transparent!important;color:var(--datepicker-subtle-text-color, #9ca3af)}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;position:relative;z-index:2;gap:4px}.ngxsmk-month-year-selects{display:flex;gap:4px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 100px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 75px}.ngxsmk-nav-buttons{display:flex}.ngxsmk-nav-button{padding:6px;background:none;border:none;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-nav-button:hover:not(:disabled){background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button:disabled{cursor:not-allowed;opacity:.5}.ngxsmk-nav-button svg{width:16px;height:16px}.ngxsmk-days-grid-wrapper{overflow-x:hidden}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0;transition:transform .3s ease-out,opacity .15s ease-out .15s}.ngxsmk-days-grid.animate-forward{transform:translate(-100%);opacity:0}.ngxsmk-days-grid.animate-backward{transform:translate(100%);opacity:0}.ngxsmk-day-name{font-size:.75rem;padding:6px 0;color:var(--datepicker-subtle-text-color);font-weight:600}.ngxsmk-day-cell{height:32px;position:relative;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-cell.holiday .ngxsmk-day-number{color:var(--datepicker-primary-color);text-decoration:underline dotted}.ngxsmk-day-number{width:30px;height:30px;display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);font-size:.9rem;position:relative;z-index:1}.ngxsmk-time-selection{display:flex;align-items:center;gap:5px;flex-wrap:wrap;margin-top:12px;padding-top:8px;border-top:1px solid var(--datepicker-border-color)}.ngxsmk-time-label{font-size:.9rem;color:var(--datepicker-subtle-text-color);margin-right:4px}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}.ngxsmk-time-selection app-custom-select{--custom-select-width: 55px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 65px}.ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number{background-color:var(--datepicker-hover-background);color:var(--datepicker-primary-color)}.ngxsmk-day-cell.start-date .ngxsmk-day-number,.ngxsmk-day-cell.end-date .ngxsmk-day-number,.ngxsmk-day-cell.selected .ngxsmk-day-number,.ngxsmk-day-cell.multiple-selected .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.multiple-selected .ngxsmk-day-number{border:1px dashed var(--datepicker-primary-contrast)}.ngxsmk-day-cell.multiple-selected:hover .ngxsmk-day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.ngxsmk-day-cell.in-range,.ngxsmk-day-cell.start-date,.ngxsmk-day-cell.end-date,.ngxsmk-day-cell.preview-range{background-color:var(--datepicker-range-background)}.ngxsmk-day-cell.start-date{border-top-left-radius:100%;border-bottom-left-radius:100%}.ngxsmk-day-cell.end-date{border-top-right-radius:100%;border-bottom-right-radius:100%}.ngxsmk-day-cell.start-date.end-date{border-radius:50px}.ngxsmk-day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.ngxsmk-day-cell.today .ngxsmk-day-number{border:1px solid var(--datepicker-primary-color)}@media (min-width: 600px){.ngxsmk-datepicker-container{display:flex;flex-direction:row}.ngxsmk-calendar-container{padding:16px;box-shadow:0 4px 10px #0000001a;width:auto;border-radius:0 10px 10px 0}.ngxsmk-ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);border-bottom:none;background:var(--datepicker-background);border-radius:10px 0 0 10px}.ngxsmk-ranges-container ul{flex-direction:column;justify-content:flex-start;gap:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border:none;font-size:1rem}.ngxsmk-header{margin-bottom:12px;gap:5px}.ngxsmk-month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.ngxsmk-month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.ngxsmk-nav-button{padding:8px}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:.8rem;padding:8px 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:1rem}.ngxsmk-time-selection{margin-top:16px;padding-top:12px}.ngxsmk-time-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}}\n"] }]
601
1078
  }], propDecorators: { mode: [{
602
1079
  type: Input
603
1080
  }], isInvalidDate: [{
@@ -608,7 +1085,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
608
1085
  type: Input
609
1086
  }], minuteInterval: [{
610
1087
  type: Input
611
- }], value: [{
1088
+ }], holidayProvider: [{
1089
+ type: Input
1090
+ }], disableHolidays: [{
1091
+ type: Input
1092
+ }], placeholder: [{
1093
+ type: Input
1094
+ }], inline: [{
612
1095
  type: Input
613
1096
  }], startAt: [{
614
1097
  type: Input
@@ -619,14 +1102,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
619
1102
  }], isDarkMode: [{
620
1103
  type: HostBinding,
621
1104
  args: ['class.dark-theme']
1105
+ }], disabledState: [{
1106
+ type: Input
622
1107
  }], valueChange: [{
623
1108
  type: Output
1109
+ }], action: [{
1110
+ type: Output
624
1111
  }], minDate: [{
625
1112
  type: Input
626
1113
  }], maxDate: [{
627
1114
  type: Input
628
1115
  }], ranges: [{
629
1116
  type: Input
1117
+ }], onDocumentClick: [{
1118
+ type: HostListener,
1119
+ args: ['document:click', ['$event']]
630
1120
  }] } });
631
1121
 
632
1122
  /*
@@ -637,5 +1127,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
637
1127
  * Generated bundle index. Do not edit.
638
1128
  */
639
1129
 
640
- export { CustomSelectComponent, NgxsmkDatepickerComponent };
1130
+ export { CustomSelectComponent, NgxsmkDatepickerComponent, addMonths, generateMonthOptions, generateTimeOptions, generateWeekDays, generateYearOptions, get24Hour, getEndOfDay, getEndOfMonth, getFirstDayOfWeek, getStartOfDay, getStartOfMonth, isSameDay, normalizeDate, processDateRanges, subtractDays, update12HourState };
641
1131
  //# sourceMappingURL=ngxsmk-datepicker.mjs.map