ngxsmk-datepicker 1.4.6 → 1.4.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.
@@ -0,0 +1,1117 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, inject, ElementRef, HostListener, Output, Input, Component, forwardRef, HostBinding, ChangeDetectionStrategy } from '@angular/core';
3
+ import * as i1 from '@angular/common';
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
+ }
145
+
146
+ class CustomSelectComponent {
147
+ constructor() {
148
+ this.options = [];
149
+ this.disabled = false;
150
+ this.valueChange = new EventEmitter();
151
+ this.isOpen = false;
152
+ this.elementRef = inject(ElementRef);
153
+ }
154
+ onDocumentClick(event) {
155
+ if (!this.elementRef.nativeElement.contains(event.target))
156
+ this.isOpen = false;
157
+ }
158
+ get displayValue() {
159
+ const selectedOption = this.options.find((opt) => opt.value === this.value);
160
+ return selectedOption ? selectedOption.label : '';
161
+ }
162
+ toggleDropdown() {
163
+ if (this.disabled)
164
+ return;
165
+ this.isOpen = !this.isOpen;
166
+ }
167
+ selectOption(option) {
168
+ this.value = option.value;
169
+ this.valueChange.emit(this.value);
170
+ this.isOpen = false;
171
+ }
172
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: CustomSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
173
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.6", 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: `
174
+ <div class="ngxsmk-select-container" (click)="toggleDropdown()">
175
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
176
+ <span>{{ displayValue }}</span>
177
+ <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
178
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
179
+ d="M112 184l144 144 144-144"/>
180
+ </svg>
181
+ </button>
182
+ @if (isOpen) {
183
+ <div class="ngxsmk-options-panel">
184
+ <ul>
185
+ @for (option of options; track option.value) {
186
+ <li [class.selected]="option.value === value" (click)="selectOption(option); $event.stopPropagation()">
187
+ {{ option.label }}
188
+ </li>
189
+ }
190
+ </ul>
191
+ </div>
192
+ }
193
+ </div>
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 }] }); }
195
+ }
196
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: CustomSelectComponent, decorators: [{
197
+ type: Component,
198
+ args: [{ selector: 'ngxsmk-custom-select', standalone: true, imports: [CommonModule], template: `
199
+ <div class="ngxsmk-select-container" (click)="toggleDropdown()">
200
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
201
+ <span>{{ displayValue }}</span>
202
+ <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
203
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
204
+ d="M112 184l144 144 144-144"/>
205
+ </svg>
206
+ </button>
207
+ @if (isOpen) {
208
+ <div class="ngxsmk-options-panel">
209
+ <ul>
210
+ @for (option of options; track option.value) {
211
+ <li [class.selected]="option.value === value" (click)="selectOption(option); $event.stopPropagation()">
212
+ {{ option.label }}
213
+ </li>
214
+ }
215
+ </ul>
216
+ </div>
217
+ }
218
+ </div>
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"] }]
220
+ }], propDecorators: { options: [{
221
+ type: Input
222
+ }], value: [{
223
+ type: Input
224
+ }], disabled: [{
225
+ type: Input
226
+ }], valueChange: [{
227
+ type: Output
228
+ }], onDocumentClick: [{
229
+ type: HostListener,
230
+ args: ['document:click', ['$event']]
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
+
328
+ class NgxsmkDatepickerComponent {
329
+ constructor() {
330
+ this.mode = 'single';
331
+ this.isInvalidDate = () => false;
332
+ this.showRanges = true;
333
+ this.showTime = false;
334
+ this.minuteInterval = 1;
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;
343
+ this._startAtDate = null;
344
+ this._locale = 'en-US';
345
+ this.theme = 'light';
346
+ this.onChange = (_) => { };
347
+ this.onTouched = () => { };
348
+ this.disabled = false;
349
+ this.valueChange = new EventEmitter();
350
+ this.action = new EventEmitter();
351
+ this._minDate = null;
352
+ this._maxDate = null;
353
+ this._ranges = null;
354
+ this.currentDate = new Date();
355
+ this.daysInMonth = [];
356
+ this.weekDays = [];
357
+ this.today = getStartOfDay(new Date());
358
+ this.selectedDate = null;
359
+ this.selectedDates = [];
360
+ this.startDate = null;
361
+ this.endDate = null;
362
+ this.hoveredDate = null;
363
+ this.rangesArray = [];
364
+ this._currentMonth = this.currentDate.getMonth();
365
+ this._currentYear = this.currentDate.getFullYear();
366
+ this.monthOptions = [];
367
+ this.yearOptions = [];
368
+ this.firstDayOfWeek = 0;
369
+ this.currentHour = 0;
370
+ this.currentMinute = 0;
371
+ this.currentDisplayHour = 12;
372
+ this.isPm = false;
373
+ this.hourOptions = [];
374
+ this.minuteOptions = [];
375
+ this.ampmOptions = [
376
+ { label: 'AM', value: false },
377
+ { label: 'PM', value: true }
378
+ ];
379
+ // Animation state properties
380
+ this.elementRef = inject(ElementRef);
381
+ this.dateComparator = createDateComparator();
382
+ }
383
+ set startAt(value) { this._startAtDate = this._normalizeDate(value); }
384
+ set locale(value) { this._locale = value; }
385
+ get locale() { return this._locale; }
386
+ get isDarkMode() { return this.theme === 'dark'; }
387
+ set disabledState(isDisabled) { this.disabled = isDisabled; }
388
+ set minDate(value) { this._minDate = this._normalizeDate(value); }
389
+ set maxDate(value) { this._maxDate = this._normalizeDate(value); }
390
+ set ranges(value) {
391
+ this._ranges = processDateRanges(value);
392
+ this.updateRangesArray();
393
+ }
394
+ get isInlineMode() {
395
+ return this.inline === true || this.inline === 'always' ||
396
+ (this.inline === 'auto' && typeof window !== 'undefined' && window.matchMedia('(min-width: 768px)').matches);
397
+ }
398
+ get isCalendarVisible() {
399
+ return this.isInlineMode || this.isCalendarOpen;
400
+ }
401
+ get displayValue() {
402
+ if (this.mode === 'single' && this.selectedDate) {
403
+ return this.selectedDate.toLocaleString(this.locale, {
404
+ year: 'numeric', month: 'short', day: '2-digit',
405
+ hour: this.showTime ? '2-digit' : undefined,
406
+ minute: this.showTime ? '2-digit' : undefined
407
+ });
408
+ }
409
+ else if (this.mode === 'range' && this.startDate && this.endDate) {
410
+ const start = this.startDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
411
+ const end = this.endDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
412
+ return `${start} - ${end}`;
413
+ }
414
+ else if (this.mode === 'multiple' && this.selectedDates.length > 0) {
415
+ return `${this.selectedDates.length} dates selected`;
416
+ }
417
+ return '';
418
+ }
419
+ get isBackArrowDisabled() {
420
+ if (!this._minDate)
421
+ return false;
422
+ // Get the first day of the current month
423
+ const firstDayOfCurrentMonth = new Date(this.currentYear, this.currentMonth, 1);
424
+ // Check if the first day of current month is before or equal to minDate
425
+ return firstDayOfCurrentMonth <= this._minDate;
426
+ }
427
+ onDocumentClick(event) {
428
+ if (!this.isInlineMode && this.isCalendarOpen && !this.elementRef.nativeElement.contains(event.target)) {
429
+ this.isCalendarOpen = false;
430
+ }
431
+ }
432
+ writeValue(val) {
433
+ this._internalValue = val;
434
+ this.initializeValue(val);
435
+ this.generateCalendar();
436
+ }
437
+ registerOnChange(fn) {
438
+ this.onChange = fn;
439
+ }
440
+ registerOnTouched(fn) {
441
+ this.onTouched = fn;
442
+ }
443
+ setDisabledState(isDisabled) {
444
+ this.disabled = isDisabled;
445
+ }
446
+ emitValue(val) {
447
+ this._internalValue = val;
448
+ this.valueChange.emit(val);
449
+ this.onChange(val);
450
+ this.onTouched();
451
+ // Auto-close popover when a selection is complete
452
+ if (!this.isInlineMode && val !== null) {
453
+ if (this.mode === 'single' || (this.mode === 'range' && this.startDate && this.endDate)) {
454
+ this.isCalendarOpen = false;
455
+ }
456
+ }
457
+ }
458
+ toggleCalendar() {
459
+ if (this.disabled || this.isInlineMode)
460
+ return;
461
+ this.isCalendarOpen = !this.isCalendarOpen;
462
+ }
463
+ clearValue(event) {
464
+ if (event)
465
+ event.stopPropagation();
466
+ if (this.disabled)
467
+ return;
468
+ this.selectedDate = null;
469
+ this.selectedDates = [];
470
+ this.startDate = null;
471
+ this.endDate = null;
472
+ this.hoveredDate = null;
473
+ this.isCalendarOpen = false;
474
+ this.emitValue(null);
475
+ this.action.emit({ type: 'clear', payload: null });
476
+ // Reset view to today after clearing
477
+ this.currentDate = new Date();
478
+ this._currentMonth = this.currentDate.getMonth();
479
+ this._currentYear = this.currentDate.getFullYear();
480
+ this.generateCalendar();
481
+ }
482
+ get currentMonth() { return this._currentMonth; }
483
+ set currentMonth(month) {
484
+ if (this.disabled)
485
+ return;
486
+ if (this._currentMonth !== month) {
487
+ this._currentMonth = month;
488
+ this.currentDate.setMonth(month);
489
+ this.generateCalendar();
490
+ }
491
+ }
492
+ get currentYear() { return this._currentYear; }
493
+ set currentYear(year) {
494
+ if (this.disabled)
495
+ return;
496
+ if (this._currentYear !== year) {
497
+ this._currentYear = year;
498
+ this.currentDate.setFullYear(year);
499
+ this.generateCalendar();
500
+ }
501
+ }
502
+ ngOnInit() {
503
+ if (this._locale === 'en-US' && typeof navigator !== 'undefined') {
504
+ this._locale = navigator.language;
505
+ }
506
+ this.today.setHours(0, 0, 0, 0);
507
+ this.generateLocaleData();
508
+ this.generateTimeOptions();
509
+ if (this.showTime && !this._internalValue) {
510
+ const now = new Date();
511
+ this.currentHour = now.getHours();
512
+ this.currentMinute = Math.floor(now.getMinutes() / this.minuteInterval) * this.minuteInterval;
513
+ if (this.currentMinute === 60) {
514
+ this.currentMinute = 0;
515
+ this.currentHour = (this.currentHour + 1) % 24;
516
+ }
517
+ this.update12HourState(this.currentHour);
518
+ }
519
+ if (this._internalValue) {
520
+ this.initializeValue(this._internalValue);
521
+ }
522
+ else if (this._startAtDate) {
523
+ this.initializeValue(null);
524
+ }
525
+ this.generateCalendar();
526
+ }
527
+ ngOnChanges(changes) {
528
+ if (changes['locale']) {
529
+ this.generateLocaleData();
530
+ this.generateCalendar();
531
+ }
532
+ if (changes['minuteInterval']) {
533
+ this.generateTimeOptions();
534
+ this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;
535
+ this.onTimeChange();
536
+ }
537
+ if (changes['value'] && changes['value'].currentValue !== changes['value'].previousValue) {
538
+ this.writeValue(changes['value'].currentValue);
539
+ }
540
+ // Rerun calendar generation if provider changes to refresh disabled states
541
+ if (changes['holidayProvider'] || changes['disableHolidays']) {
542
+ this.generateCalendar();
543
+ }
544
+ if (changes['startAt']) {
545
+ if (!this._internalValue && this._startAtDate) {
546
+ this.currentDate = new Date(this._startAtDate);
547
+ this._currentMonth = this.currentDate.getMonth();
548
+ this._currentYear = this.currentDate.getFullYear();
549
+ this.generateCalendar();
550
+ }
551
+ }
552
+ }
553
+ get24Hour(displayHour, isPm) {
554
+ return get24Hour(displayHour, isPm);
555
+ }
556
+ update12HourState(fullHour) {
557
+ const state = update12HourState(fullHour);
558
+ this.isPm = state.isPm;
559
+ this.currentDisplayHour = state.displayHour;
560
+ }
561
+ applyCurrentTime(date) {
562
+ this.currentHour = this.get24Hour(this.currentDisplayHour, this.isPm);
563
+ date.setHours(this.currentHour, this.currentMinute, 0, 0);
564
+ return date;
565
+ }
566
+ initializeValue(value) {
567
+ let initialDate = null;
568
+ this.selectedDate = null;
569
+ this.startDate = null;
570
+ this.endDate = null;
571
+ this.selectedDates = [];
572
+ if (value) {
573
+ if (this.mode === 'single' && value instanceof Date) {
574
+ this.selectedDate = this._normalizeDate(value);
575
+ initialDate = this.selectedDate;
576
+ }
577
+ else if (this.mode === 'range' && typeof value === 'object' && 'start' in value && 'end' in value) {
578
+ this.startDate = this._normalizeDate(value.start);
579
+ this.endDate = this._normalizeDate(value.end);
580
+ initialDate = this.startDate;
581
+ }
582
+ else if (this.mode === 'multiple' && Array.isArray(value)) {
583
+ this.selectedDates = value.map(d => this._normalizeDate(d)).filter((d) => d !== null);
584
+ initialDate = this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
585
+ }
586
+ }
587
+ const viewCenterDate = initialDate || this._startAtDate || new Date();
588
+ if (viewCenterDate) {
589
+ this.currentDate = new Date(viewCenterDate);
590
+ this._currentMonth = viewCenterDate.getMonth();
591
+ this._currentYear = viewCenterDate.getFullYear();
592
+ this.currentHour = viewCenterDate.getHours();
593
+ this.currentMinute = viewCenterDate.getMinutes();
594
+ this.update12HourState(this.currentHour);
595
+ this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;
596
+ }
597
+ }
598
+ _normalizeDate(date) {
599
+ return normalizeDate(date);
600
+ }
601
+ generateTimeOptions() {
602
+ const { hourOptions, minuteOptions } = generateTimeOptions(this.minuteInterval);
603
+ this.hourOptions = hourOptions;
604
+ this.minuteOptions = minuteOptions;
605
+ }
606
+ generateLocaleData() {
607
+ const year = new Date().getFullYear();
608
+ this.monthOptions = generateMonthOptions(this.locale, year);
609
+ this.firstDayOfWeek = getFirstDayOfWeek(this.locale);
610
+ this.weekDays = generateWeekDays(this.locale, this.firstDayOfWeek);
611
+ }
612
+ updateRangesArray() {
613
+ this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({ key, value })) : [];
614
+ }
615
+ selectRange(range) {
616
+ if (this.disabled)
617
+ return;
618
+ this.startDate = this.applyCurrentTime(range[0]);
619
+ this.endDate = this.applyCurrentTime(range[1]);
620
+ if (this.startDate && this.endDate) {
621
+ this.emitValue({ start: this.startDate, end: this.endDate });
622
+ }
623
+ this.currentDate = new Date(this.startDate);
624
+ this.initializeValue({ start: this.startDate, end: this.endDate });
625
+ this.generateCalendar();
626
+ this.action.emit({ type: 'rangeSelected', payload: { start: this.startDate, end: this.endDate, key: this.rangesArray.find(r => r.value === range)?.key } });
627
+ }
628
+ // NEW: Check if a date is a holiday
629
+ isHoliday(date) {
630
+ if (!date || !this.holidayProvider)
631
+ return false;
632
+ const dateOnly = getStartOfDay(date);
633
+ return this.holidayProvider.isHoliday(dateOnly);
634
+ }
635
+ // NEW: Get holiday label
636
+ getHolidayLabel(date) {
637
+ if (!date || !this.holidayProvider || !this.isHoliday(date))
638
+ return null;
639
+ return this.holidayProvider.getHolidayLabel ? this.holidayProvider.getHolidayLabel(getStartOfDay(date)) : 'Holiday';
640
+ }
641
+ isDateDisabled(date) {
642
+ if (!date)
643
+ return false;
644
+ const dateOnly = getStartOfDay(date);
645
+ // 1. Check holiday provider for disabling
646
+ if (this.holidayProvider && this.disableHolidays && this.holidayProvider.isHoliday(dateOnly)) {
647
+ return true;
648
+ }
649
+ // 2. Check min/max date
650
+ if (this._minDate) {
651
+ const minDateOnly = getStartOfDay(this._minDate);
652
+ if (dateOnly.getTime() < minDateOnly.getTime())
653
+ return true;
654
+ }
655
+ if (this._maxDate) {
656
+ const maxDateOnly = getStartOfDay(this._maxDate);
657
+ if (dateOnly.getTime() > maxDateOnly.getTime())
658
+ return true;
659
+ }
660
+ // 3. Check custom invalid date function
661
+ return this.isInvalidDate(date);
662
+ }
663
+ isMultipleSelected(d) {
664
+ if (!d || this.mode !== 'multiple')
665
+ return false;
666
+ const dTime = getStartOfDay(d).getTime();
667
+ return this.selectedDates.some(selected => getStartOfDay(selected).getTime() === dTime);
668
+ }
669
+ onTimeChange() {
670
+ if (this.disabled)
671
+ return;
672
+ if (this.mode === 'single' && this.selectedDate) {
673
+ this.selectedDate = this.applyCurrentTime(this.selectedDate);
674
+ this.emitValue(this.selectedDate);
675
+ }
676
+ else if (this.mode === 'range' && this.startDate && this.endDate) {
677
+ this.startDate = this.applyCurrentTime(this.startDate);
678
+ this.endDate = this.applyCurrentTime(this.endDate);
679
+ this.emitValue({ start: this.startDate, end: this.endDate });
680
+ }
681
+ else if (this.mode === 'range' && this.startDate && !this.endDate) {
682
+ this.startDate = this.applyCurrentTime(this.startDate);
683
+ }
684
+ else if (this.mode === 'multiple') {
685
+ this.selectedDates = this.selectedDates.map(date => {
686
+ const newDate = getStartOfDay(date);
687
+ return this.applyCurrentTime(newDate);
688
+ });
689
+ this.emitValue([...this.selectedDates]);
690
+ }
691
+ this.action.emit({ type: 'timeChanged', payload: { hour: this.currentHour, minute: this.currentMinute } });
692
+ }
693
+ onDateClick(day) {
694
+ if (!day || this.isDateDisabled(day) || this.disabled)
695
+ return;
696
+ const dateToToggle = getStartOfDay(day);
697
+ if (this.mode === 'single') {
698
+ this.selectedDate = this.applyCurrentTime(day);
699
+ this.emitValue(this.selectedDate);
700
+ }
701
+ else if (this.mode === 'range') {
702
+ if (!this.startDate || (this.startDate && this.endDate)) {
703
+ this.startDate = this.applyCurrentTime(day);
704
+ this.endDate = null;
705
+ }
706
+ else if (day >= this.startDate) {
707
+ this.endDate = this.applyCurrentTime(day);
708
+ this.emitValue({ start: this.startDate, end: this.endDate });
709
+ }
710
+ else {
711
+ this.startDate = this.applyCurrentTime(day);
712
+ this.endDate = null;
713
+ }
714
+ this.hoveredDate = null;
715
+ }
716
+ else if (this.mode === 'multiple') {
717
+ const existingIndex = this.selectedDates.findIndex(d => this.isSameDay(d, dateToToggle));
718
+ if (existingIndex > -1) {
719
+ this.selectedDates.splice(existingIndex, 1);
720
+ }
721
+ else {
722
+ const dateWithTime = this.applyCurrentTime(dateToToggle);
723
+ this.selectedDates.push(dateWithTime);
724
+ this.selectedDates.sort((a, b) => a.getTime() - b.getTime());
725
+ }
726
+ this.emitValue([...this.selectedDates]);
727
+ }
728
+ const dateToSync = this.mode === 'single' ? this.selectedDate :
729
+ this.mode === 'range' ? this.startDate :
730
+ this.mode === 'multiple' && this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
731
+ if (dateToSync) {
732
+ this.update12HourState(dateToSync.getHours());
733
+ this.currentMinute = dateToSync.getMinutes();
734
+ }
735
+ this.action.emit({
736
+ type: 'dateSelected',
737
+ payload: {
738
+ mode: this.mode,
739
+ value: this._internalValue,
740
+ date: day
741
+ }
742
+ });
743
+ }
744
+ onDateHover(day) {
745
+ if (this.mode === 'range' && this.startDate && !this.endDate && day) {
746
+ this.hoveredDate = day;
747
+ }
748
+ }
749
+ isPreviewInRange(day) {
750
+ if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day)
751
+ return false;
752
+ const start = getStartOfDay(this.startDate).getTime();
753
+ const end = getStartOfDay(this.hoveredDate).getTime();
754
+ const time = getStartOfDay(day).getTime();
755
+ return time > Math.min(start, end) && time < Math.max(start, end);
756
+ }
757
+ generateCalendar() {
758
+ this.daysInMonth = [];
759
+ const year = this.currentDate.getFullYear();
760
+ const month = this.currentDate.getMonth();
761
+ this._currentMonth = month;
762
+ this._currentYear = year;
763
+ this.generateDropdownOptions();
764
+ const firstDayOfMonth = new Date(year, month, 1);
765
+ const lastDayOfMonth = new Date(year, month + 1, 0);
766
+ const startDayOfWeek = firstDayOfMonth.getDay();
767
+ const emptyCellCount = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;
768
+ for (let i = 0; i < emptyCellCount; i++) {
769
+ this.daysInMonth.push(null);
770
+ }
771
+ for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
772
+ this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));
773
+ }
774
+ this.action.emit({
775
+ type: 'calendarGenerated',
776
+ payload: {
777
+ month: month,
778
+ year: year,
779
+ days: this.daysInMonth.filter(d => d !== null)
780
+ }
781
+ });
782
+ }
783
+ generateDropdownOptions() {
784
+ this.yearOptions = generateYearOptions(this._currentYear);
785
+ }
786
+ changeMonth(delta) {
787
+ if (this.disabled)
788
+ return;
789
+ // Check if going back is disabled due to minDate constraint
790
+ if (delta < 0 && this.isBackArrowDisabled)
791
+ return;
792
+ const newDate = addMonths(this.currentDate, delta);
793
+ // Update the data immediately (no animation)
794
+ this.currentDate = newDate;
795
+ this._currentMonth = newDate.getMonth();
796
+ this._currentYear = newDate.getFullYear();
797
+ // Generate new calendar view
798
+ this.generateCalendar();
799
+ this.action.emit({ type: 'monthChanged', payload: { delta: delta } });
800
+ }
801
+ isSameDay(d1, d2) {
802
+ return this.dateComparator(d1, d2);
803
+ }
804
+ isInRange(d) {
805
+ if (!d || !this.startDate || !this.endDate)
806
+ return false;
807
+ const dTime = getStartOfDay(d).getTime();
808
+ const startDayTime = getStartOfDay(this.startDate).getTime();
809
+ const endDayTime = getStartOfDay(this.endDate).getTime();
810
+ const startTime = Math.min(startDayTime, endDayTime);
811
+ const endTime = Math.max(startDayTime, endDayTime);
812
+ return dTime > startTime && dTime < endTime;
813
+ }
814
+ ngOnDestroy() {
815
+ // Clean up any subscriptions or timers if needed
816
+ // Currently no cleanup required, but method is here for future optimizations
817
+ }
818
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: NgxsmkDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
819
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.6", 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: [{
820
+ provide: NG_VALUE_ACCESSOR,
821
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
822
+ multi: true
823
+ }], usesOnChanges: true, ngImport: i0, template: `
824
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
825
+ @if (!isInlineMode) {
826
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
827
+ <input type="text"
828
+ [value]="displayValue"
829
+ [placeholder]="placeholder"
830
+ readonly
831
+ [disabled]="disabled"
832
+ class="ngxsmk-display-input">
833
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
834
+ <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>
835
+ </button>
836
+ </div>
837
+ }
838
+
839
+ @if (isCalendarVisible) {
840
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
841
+ <div class="ngxsmk-datepicker-container">
842
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
843
+ <div class="ngxsmk-ranges-container">
844
+ <ul>
845
+ @for (range of rangesArray; track range.key) {
846
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
847
+ }
848
+ </ul>
849
+ </div>
850
+ }
851
+ <div class="ngxsmk-calendar-container">
852
+ <div class="ngxsmk-header">
853
+ <div class="ngxsmk-month-year-selects">
854
+ <ngxsmk-custom-select class="month-select" [options]="monthOptions"
855
+ [(value)]="currentMonth" [disabled]="disabled"></ngxsmk-custom-select>
856
+ <ngxsmk-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></ngxsmk-custom-select>
857
+ </div>
858
+ <div class="ngxsmk-nav-buttons">
859
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled || isBackArrowDisabled">
860
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
861
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
862
+ d="M328 112L184 256l144 144"/>
863
+ </svg>
864
+ </button>
865
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
866
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
867
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
868
+ d="M184 112l144 144-144 144"/>
869
+ </svg>
870
+ </button>
871
+ </div>
872
+ </div>
873
+ <div class="ngxsmk-days-grid-wrapper">
874
+ <div class="ngxsmk-days-grid">
875
+ @for (day of weekDays; track day) {
876
+ <div class="ngxsmk-day-name">{{ day }}</div>
877
+ }
878
+ @for (day of daysInMonth; track $index) {
879
+ <div class="ngxsmk-day-cell"
880
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
881
+ [class.today]="isSameDay(day, today)"
882
+ [class.holiday]="isHoliday(day)"
883
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
884
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
885
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
886
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
887
+ [class.in-range]="mode === 'range' && isInRange(day)"
888
+ [class.preview-range]="isPreviewInRange(day)"
889
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
890
+ @if (day) {
891
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
892
+ }
893
+ </div>
894
+ }
895
+ </div>
896
+ </div>
897
+
898
+ @if (showTime) {
899
+ <div class="ngxsmk-time-selection">
900
+ <span class="ngxsmk-time-label">Time:</span>
901
+ <ngxsmk-custom-select
902
+ class="hour-select"
903
+ [options]="hourOptions"
904
+ [(value)]="currentDisplayHour"
905
+ (valueChange)="onTimeChange()"
906
+ [disabled]="disabled"
907
+ ></ngxsmk-custom-select>
908
+ <span class="ngxsmk-time-separator">:</span>
909
+ <ngxsmk-custom-select
910
+ class="minute-select"
911
+ [options]="minuteOptions"
912
+ [(value)]="currentMinute"
913
+ (valueChange)="onTimeChange()"
914
+ [disabled]="disabled"
915
+ ></ngxsmk-custom-select>
916
+ <ngxsmk-custom-select
917
+ class="ampm-select"
918
+ [options]="ampmOptions"
919
+ [(value)]="isPm"
920
+ (valueChange)="onTimeChange()"
921
+ [disabled]="disabled"
922
+ ></ngxsmk-custom-select>
923
+ </div>
924
+ }
925
+
926
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
927
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
928
+ Clear
929
+ </button>
930
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
931
+ Close
932
+ </button>
933
+ </div>
934
+ </div>
935
+ </div>
936
+ </div>
937
+ }
938
+ </div>
939
+ `, 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;--datepicker-font-size-base: 14px;--datepicker-font-size-sm: 12px;--datepicker-font-size-lg: 16px;--datepicker-font-size-xl: 18px;--datepicker-line-height: 1.4;--datepicker-spacing-xs: 4px;--datepicker-spacing-sm: 8px;--datepicker-spacing-md: 12px;--datepicker-spacing-lg: 16px;--datepicker-spacing-xl: 20px;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:all .2s ease;position:relative;overflow:hidden}.ngxsmk-input-group:focus-within{border-color:var(--datepicker-primary-color);box-shadow:0 0 0 2px #6d28d91a}.ngxsmk-input-group:hover:not(.disabled){border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.has-value{border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.error{border-color:#dc2626;box-shadow:0 0 0 2px #dc26261a}.ngxsmk-input-group.success{border-color:#16a34a;box-shadow:0 0 0 2px #16a34a1a}.ngxsmk-input-group.disabled{cursor:not-allowed;opacity:.7}.ngxsmk-display-input{flex-grow:1;padding:var(--datepicker-spacing-sm) var(--datepicker-spacing-sm);font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);color:var(--datepicker-text-color, #333);background:transparent;border:none;outline:none;cursor:pointer;transition:all .2s ease;min-height:20px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.ngxsmk-display-input:disabled{background:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed;opacity:.6}.ngxsmk-display-input:focus{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-display-input::placeholder{color:var(--datepicker-subtle-text-color);font-style:italic}.ngxsmk-input-group:focus-within .ngxsmk-display-input{color:var(--datepicker-primary-color)}.ngxsmk-input-group:hover:not(.disabled) .ngxsmk-display-input{color:var(--datepicker-text-color)}.ngxsmk-input-group.has-value .ngxsmk-display-input{font-weight:500;color:var(--datepicker-text-color)}.ngxsmk-input-group:not(.has-value) .ngxsmk-display-input{color:var(--datepicker-subtle-text-color)}.ngxsmk-input-group.error .ngxsmk-display-input{color:#dc2626;border-color:#dc2626}.ngxsmk-input-group.success .ngxsmk-display-input{color:#16a34a;border-color:#16a34a}.ngxsmk-input-group.compact{min-width:120px;padding:var(--datepicker-spacing-xs)}.ngxsmk-input-group.compact .ngxsmk-display-input{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs)}.ngxsmk-input-group.large{min-width:200px;padding:var(--datepicker-spacing-md)}.ngxsmk-input-group.large .ngxsmk-display-input{font-size:var(--datepicker-font-size-lg);padding:var(--datepicker-spacing-md)}.ngxsmk-input-group.with-icon .ngxsmk-display-input{padding-left:32px}.ngxsmk-input-group .ngxsmk-input-icon{position:absolute;left:var(--datepicker-spacing-sm);top:50%;transform:translateY(-50%);color:var(--datepicker-subtle-text-color);pointer-events:none}.ngxsmk-input-group.loading .ngxsmk-display-input{color:var(--datepicker-subtle-text-color);cursor:wait}.ngxsmk-input-group.loading:after{content:\"\";position:absolute;right:var(--datepicker-spacing-sm);top:50%;transform:translateY(-50%);width:16px;height:16px;border:2px solid var(--datepicker-border-color);border-top:2px solid var(--datepicker-primary-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:translateY(-50%) rotate(0)}to{transform:translateY(-50%) rotate(360deg)}}.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}.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:var(--datepicker-spacing-sm) var(--datepicker-spacing-md);border-radius:6px;font-size:var(--datepicker-font-size-sm);line-height:var(--datepicker-line-height);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;font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);border-radius:10px;padding:var(--datepicker-spacing-md);background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:var(--datepicker-spacing-md);border-right:none;background:var(--datepicker-hover-background);border-radius:10px}.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:var(--datepicker-spacing-sm) var(--datepicker-spacing-sm);margin-bottom:0;font-size:var(--datepicker-font-size-sm);line-height:var(--datepicker-line-height);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{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-sm) 0;color:var(--datepicker-subtle-text-color);font-weight:600;line-height:var(--datepicker-line-height)}.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:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);position:relative;z-index:1}.ngxsmk-time-selection{display:flex;align-items:center;gap:var(--datepicker-spacing-xs);flex-wrap:wrap;margin-top:var(--datepicker-spacing-md);padding-top:var(--datepicker-spacing-sm);border-top:1px solid var(--datepicker-border-color)}.ngxsmk-time-label{font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);color:var(--datepicker-subtle-text-color);margin-right:var(--datepicker-spacing-xs)}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}.ngxsmk-time-selection app-custom-select{--custom-select-width: 75px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 75px}.ngxsmk-time-selection .hour-select,.ngxsmk-time-selection .minute-select,.ngxsmk-time-selection .ampm-select{--custom-select-width: 75px;--custom-select-height: 28px}.ngxsmk-time-selection app-custom-select:hover{border-color:var(--datepicker-primary-color)}.ngxsmk-time-selection app-custom-select:focus-within{border-color:var(--datepicker-primary-color);box-shadow:0 0 0 2px #6d28d933}.ngxsmk-time-selection .time-select-compact{--custom-select-width: 60px;--custom-select-height: 24px;font-size:var(--datepicker-font-size-sm)}.ngxsmk-time-selection .time-select-large{--custom-select-width: 90px;--custom-select-height: 36px;font-size:var(--datepicker-font-size-lg)}.ngxsmk-time-selection .time-select-disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.ngxsmk-time-selection app-custom-select{transition:border-color .2s ease,box-shadow .2s ease}.ngxsmk-time-selection app-custom-select.ngxsmk-time-select-animated{transition:all .2s cubic-bezier(.4,0,.2,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,.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:var(--datepicker-spacing-lg);box-shadow:0 4px 10px #0000001a;width:auto;border-radius:10px;min-height:280px}.ngxsmk-ranges-container{width:180px;padding:var(--datepicker-spacing-lg);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:var(--datepicker-spacing-sm);margin-bottom:var(--datepicker-spacing-sm);border:none;font-size:var(--datepicker-font-size-lg)}.ngxsmk-header{margin-bottom:var(--datepicker-spacing-md);gap:var(--datepicker-spacing-xs)}.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:var(--datepicker-spacing-sm)}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:var(--datepicker-font-size-base);padding:var(--datepicker-spacing-sm) 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:var(--datepicker-font-size-lg)}.ngxsmk-time-selection{margin-top:var(--datepicker-spacing-lg);padding-top:var(--datepicker-spacing-md)}.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-time-selection .hour-select,.ngxsmk-time-selection .minute-select{--custom-select-width: 60px;--custom-select-height: 30px}.ngxsmk-time-selection .ampm-select{--custom-select-width: 70px;--custom-select-height: 30px}}@media (prefers-reduced-motion: reduce){.ngxsmk-days-grid{transition:none}.ngxsmk-days-grid.animate-forward,.ngxsmk-days-grid.animate-backward{transform:none;opacity:1}}@media (prefers-contrast: high){:host{--datepicker-border-color: #000000;--datepicker-text-color: #000000;--datepicker-subtle-text-color: #666666}.ngxsmk-day-cell.disabled{opacity:.3}}@media print{.ngxsmk-datepicker-wrapper{display:none}}.ngxsmk-day-cell:focus-visible .ngxsmk-day-number{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-nav-button:focus-visible,.ngxsmk-clear-button:focus-visible,.ngxsmk-clear-button-footer:focus-visible,.ngxsmk-close-button:focus-visible{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-day-cell,.ngxsmk-nav-button,.ngxsmk-clear-button{will-change:auto}.ngxsmk-days-grid{contain:layout style paint}@media (max-width: 480px){.ngxsmk-day-cell{height:28px}.ngxsmk-day-number{width:26px;height:26px;font-size:var(--datepicker-font-size-sm)}.ngxsmk-day-name{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs) 0}.ngxsmk-calendar-container{padding:var(--datepicker-spacing-sm)}.ngxsmk-header{margin-bottom:var(--datepicker-spacing-sm)}.ngxsmk-input-group{min-width:120px}.ngxsmk-display-input{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs)}.ngxsmk-clear-button{padding:0 var(--datepicker-spacing-xs)}.ngxsmk-clear-button svg{width:12px;height:12px}}\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 }); }
940
+ }
941
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.6", ngImport: i0, type: NgxsmkDatepickerComponent, decorators: [{
942
+ type: Component,
943
+ args: [{ selector: 'ngxsmk-datepicker', standalone: true, imports: [CommonModule, FormsModule, CustomSelectComponent, DatePipe, ReactiveFormsModule], providers: [{
944
+ provide: NG_VALUE_ACCESSOR,
945
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
946
+ multi: true
947
+ }], changeDetection: ChangeDetectionStrategy.OnPush, template: `
948
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
949
+ @if (!isInlineMode) {
950
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
951
+ <input type="text"
952
+ [value]="displayValue"
953
+ [placeholder]="placeholder"
954
+ readonly
955
+ [disabled]="disabled"
956
+ class="ngxsmk-display-input">
957
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
958
+ <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>
959
+ </button>
960
+ </div>
961
+ }
962
+
963
+ @if (isCalendarVisible) {
964
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
965
+ <div class="ngxsmk-datepicker-container">
966
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
967
+ <div class="ngxsmk-ranges-container">
968
+ <ul>
969
+ @for (range of rangesArray; track range.key) {
970
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
971
+ }
972
+ </ul>
973
+ </div>
974
+ }
975
+ <div class="ngxsmk-calendar-container">
976
+ <div class="ngxsmk-header">
977
+ <div class="ngxsmk-month-year-selects">
978
+ <ngxsmk-custom-select class="month-select" [options]="monthOptions"
979
+ [(value)]="currentMonth" [disabled]="disabled"></ngxsmk-custom-select>
980
+ <ngxsmk-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></ngxsmk-custom-select>
981
+ </div>
982
+ <div class="ngxsmk-nav-buttons">
983
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled || isBackArrowDisabled">
984
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
985
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
986
+ d="M328 112L184 256l144 144"/>
987
+ </svg>
988
+ </button>
989
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
990
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
991
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
992
+ d="M184 112l144 144-144 144"/>
993
+ </svg>
994
+ </button>
995
+ </div>
996
+ </div>
997
+ <div class="ngxsmk-days-grid-wrapper">
998
+ <div class="ngxsmk-days-grid">
999
+ @for (day of weekDays; track day) {
1000
+ <div class="ngxsmk-day-name">{{ day }}</div>
1001
+ }
1002
+ @for (day of daysInMonth; track $index) {
1003
+ <div class="ngxsmk-day-cell"
1004
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
1005
+ [class.today]="isSameDay(day, today)"
1006
+ [class.holiday]="isHoliday(day)"
1007
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
1008
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
1009
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
1010
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
1011
+ [class.in-range]="mode === 'range' && isInRange(day)"
1012
+ [class.preview-range]="isPreviewInRange(day)"
1013
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
1014
+ @if (day) {
1015
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
1016
+ }
1017
+ </div>
1018
+ }
1019
+ </div>
1020
+ </div>
1021
+
1022
+ @if (showTime) {
1023
+ <div class="ngxsmk-time-selection">
1024
+ <span class="ngxsmk-time-label">Time:</span>
1025
+ <ngxsmk-custom-select
1026
+ class="hour-select"
1027
+ [options]="hourOptions"
1028
+ [(value)]="currentDisplayHour"
1029
+ (valueChange)="onTimeChange()"
1030
+ [disabled]="disabled"
1031
+ ></ngxsmk-custom-select>
1032
+ <span class="ngxsmk-time-separator">:</span>
1033
+ <ngxsmk-custom-select
1034
+ class="minute-select"
1035
+ [options]="minuteOptions"
1036
+ [(value)]="currentMinute"
1037
+ (valueChange)="onTimeChange()"
1038
+ [disabled]="disabled"
1039
+ ></ngxsmk-custom-select>
1040
+ <ngxsmk-custom-select
1041
+ class="ampm-select"
1042
+ [options]="ampmOptions"
1043
+ [(value)]="isPm"
1044
+ (valueChange)="onTimeChange()"
1045
+ [disabled]="disabled"
1046
+ ></ngxsmk-custom-select>
1047
+ </div>
1048
+ }
1049
+
1050
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
1051
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
1052
+ Clear
1053
+ </button>
1054
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
1055
+ Close
1056
+ </button>
1057
+ </div>
1058
+ </div>
1059
+ </div>
1060
+ </div>
1061
+ }
1062
+ </div>
1063
+ `, 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;--datepicker-font-size-base: 14px;--datepicker-font-size-sm: 12px;--datepicker-font-size-lg: 16px;--datepicker-font-size-xl: 18px;--datepicker-line-height: 1.4;--datepicker-spacing-xs: 4px;--datepicker-spacing-sm: 8px;--datepicker-spacing-md: 12px;--datepicker-spacing-lg: 16px;--datepicker-spacing-xl: 20px;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:all .2s ease;position:relative;overflow:hidden}.ngxsmk-input-group:focus-within{border-color:var(--datepicker-primary-color);box-shadow:0 0 0 2px #6d28d91a}.ngxsmk-input-group:hover:not(.disabled){border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.has-value{border-color:var(--datepicker-primary-color)}.ngxsmk-input-group.error{border-color:#dc2626;box-shadow:0 0 0 2px #dc26261a}.ngxsmk-input-group.success{border-color:#16a34a;box-shadow:0 0 0 2px #16a34a1a}.ngxsmk-input-group.disabled{cursor:not-allowed;opacity:.7}.ngxsmk-display-input{flex-grow:1;padding:var(--datepicker-spacing-sm) var(--datepicker-spacing-sm);font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);color:var(--datepicker-text-color, #333);background:transparent;border:none;outline:none;cursor:pointer;transition:all .2s ease;min-height:20px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.ngxsmk-display-input:disabled{background:var(--datepicker-hover-background, #f0f0f0);cursor:not-allowed;opacity:.6}.ngxsmk-display-input:focus{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-display-input::placeholder{color:var(--datepicker-subtle-text-color);font-style:italic}.ngxsmk-input-group:focus-within .ngxsmk-display-input{color:var(--datepicker-primary-color)}.ngxsmk-input-group:hover:not(.disabled) .ngxsmk-display-input{color:var(--datepicker-text-color)}.ngxsmk-input-group.has-value .ngxsmk-display-input{font-weight:500;color:var(--datepicker-text-color)}.ngxsmk-input-group:not(.has-value) .ngxsmk-display-input{color:var(--datepicker-subtle-text-color)}.ngxsmk-input-group.error .ngxsmk-display-input{color:#dc2626;border-color:#dc2626}.ngxsmk-input-group.success .ngxsmk-display-input{color:#16a34a;border-color:#16a34a}.ngxsmk-input-group.compact{min-width:120px;padding:var(--datepicker-spacing-xs)}.ngxsmk-input-group.compact .ngxsmk-display-input{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs)}.ngxsmk-input-group.large{min-width:200px;padding:var(--datepicker-spacing-md)}.ngxsmk-input-group.large .ngxsmk-display-input{font-size:var(--datepicker-font-size-lg);padding:var(--datepicker-spacing-md)}.ngxsmk-input-group.with-icon .ngxsmk-display-input{padding-left:32px}.ngxsmk-input-group .ngxsmk-input-icon{position:absolute;left:var(--datepicker-spacing-sm);top:50%;transform:translateY(-50%);color:var(--datepicker-subtle-text-color);pointer-events:none}.ngxsmk-input-group.loading .ngxsmk-display-input{color:var(--datepicker-subtle-text-color);cursor:wait}.ngxsmk-input-group.loading:after{content:\"\";position:absolute;right:var(--datepicker-spacing-sm);top:50%;transform:translateY(-50%);width:16px;height:16px;border:2px solid var(--datepicker-border-color);border-top:2px solid var(--datepicker-primary-color);border-radius:50%;animation:spin 1s linear infinite}@keyframes spin{0%{transform:translateY(-50%) rotate(0)}to{transform:translateY(-50%) rotate(360deg)}}.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}.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:var(--datepicker-spacing-sm) var(--datepicker-spacing-md);border-radius:6px;font-size:var(--datepicker-font-size-sm);line-height:var(--datepicker-line-height);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;font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);border-radius:10px;padding:var(--datepicker-spacing-md);background:var(--datepicker-background);box-shadow:0 4px 10px #0000001a;width:100%}.ngxsmk-ranges-container{width:100%;padding:var(--datepicker-spacing-md);border-right:none;background:var(--datepicker-hover-background);border-radius:10px}.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:var(--datepicker-spacing-sm) var(--datepicker-spacing-sm);margin-bottom:0;font-size:var(--datepicker-font-size-sm);line-height:var(--datepicker-line-height);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{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-sm) 0;color:var(--datepicker-subtle-text-color);font-weight:600;line-height:var(--datepicker-line-height)}.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:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);position:relative;z-index:1}.ngxsmk-time-selection{display:flex;align-items:center;gap:var(--datepicker-spacing-xs);flex-wrap:wrap;margin-top:var(--datepicker-spacing-md);padding-top:var(--datepicker-spacing-sm);border-top:1px solid var(--datepicker-border-color)}.ngxsmk-time-label{font-size:var(--datepicker-font-size-base);line-height:var(--datepicker-line-height);color:var(--datepicker-subtle-text-color);margin-right:var(--datepicker-spacing-xs)}.ngxsmk-time-separator{font-weight:600;color:var(--datepicker-text-color)}.ngxsmk-time-selection app-custom-select{--custom-select-width: 75px;height:28px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 75px}.ngxsmk-time-selection .hour-select,.ngxsmk-time-selection .minute-select,.ngxsmk-time-selection .ampm-select{--custom-select-width: 75px;--custom-select-height: 28px}.ngxsmk-time-selection app-custom-select:hover{border-color:var(--datepicker-primary-color)}.ngxsmk-time-selection app-custom-select:focus-within{border-color:var(--datepicker-primary-color);box-shadow:0 0 0 2px #6d28d933}.ngxsmk-time-selection .time-select-compact{--custom-select-width: 60px;--custom-select-height: 24px;font-size:var(--datepicker-font-size-sm)}.ngxsmk-time-selection .time-select-large{--custom-select-width: 90px;--custom-select-height: 36px;font-size:var(--datepicker-font-size-lg)}.ngxsmk-time-selection .time-select-disabled{opacity:.6;cursor:not-allowed;pointer-events:none}.ngxsmk-time-selection app-custom-select{transition:border-color .2s ease,box-shadow .2s ease}.ngxsmk-time-selection app-custom-select.ngxsmk-time-select-animated{transition:all .2s cubic-bezier(.4,0,.2,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,.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:var(--datepicker-spacing-lg);box-shadow:0 4px 10px #0000001a;width:auto;border-radius:10px;min-height:280px}.ngxsmk-ranges-container{width:180px;padding:var(--datepicker-spacing-lg);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:var(--datepicker-spacing-sm);margin-bottom:var(--datepicker-spacing-sm);border:none;font-size:var(--datepicker-font-size-lg)}.ngxsmk-header{margin-bottom:var(--datepicker-spacing-md);gap:var(--datepicker-spacing-xs)}.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:var(--datepicker-spacing-sm)}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-day-name{font-size:var(--datepicker-font-size-base);padding:var(--datepicker-spacing-sm) 0}.ngxsmk-day-cell{height:38px}.ngxsmk-day-number{width:36px;height:36px;font-size:var(--datepicker-font-size-lg)}.ngxsmk-time-selection{margin-top:var(--datepicker-spacing-lg);padding-top:var(--datepicker-spacing-md)}.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-time-selection .hour-select,.ngxsmk-time-selection .minute-select{--custom-select-width: 60px;--custom-select-height: 30px}.ngxsmk-time-selection .ampm-select{--custom-select-width: 70px;--custom-select-height: 30px}}@media (prefers-reduced-motion: reduce){.ngxsmk-days-grid{transition:none}.ngxsmk-days-grid.animate-forward,.ngxsmk-days-grid.animate-backward{transform:none;opacity:1}}@media (prefers-contrast: high){:host{--datepicker-border-color: #000000;--datepicker-text-color: #000000;--datepicker-subtle-text-color: #666666}.ngxsmk-day-cell.disabled{opacity:.3}}@media print{.ngxsmk-datepicker-wrapper{display:none}}.ngxsmk-day-cell:focus-visible .ngxsmk-day-number{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-nav-button:focus-visible,.ngxsmk-clear-button:focus-visible,.ngxsmk-clear-button-footer:focus-visible,.ngxsmk-close-button:focus-visible{outline:2px solid var(--datepicker-primary-color);outline-offset:2px}.ngxsmk-day-cell,.ngxsmk-nav-button,.ngxsmk-clear-button{will-change:auto}.ngxsmk-days-grid{contain:layout style paint}@media (max-width: 480px){.ngxsmk-day-cell{height:28px}.ngxsmk-day-number{width:26px;height:26px;font-size:var(--datepicker-font-size-sm)}.ngxsmk-day-name{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs) 0}.ngxsmk-calendar-container{padding:var(--datepicker-spacing-sm)}.ngxsmk-header{margin-bottom:var(--datepicker-spacing-sm)}.ngxsmk-input-group{min-width:120px}.ngxsmk-display-input{font-size:var(--datepicker-font-size-sm);padding:var(--datepicker-spacing-xs)}.ngxsmk-clear-button{padding:0 var(--datepicker-spacing-xs)}.ngxsmk-clear-button svg{width:12px;height:12px}}\n"] }]
1064
+ }], propDecorators: { mode: [{
1065
+ type: Input
1066
+ }], isInvalidDate: [{
1067
+ type: Input
1068
+ }], showRanges: [{
1069
+ type: Input
1070
+ }], showTime: [{
1071
+ type: Input
1072
+ }], minuteInterval: [{
1073
+ type: Input
1074
+ }], holidayProvider: [{
1075
+ type: Input
1076
+ }], disableHolidays: [{
1077
+ type: Input
1078
+ }], placeholder: [{
1079
+ type: Input
1080
+ }], inline: [{
1081
+ type: Input
1082
+ }], startAt: [{
1083
+ type: Input
1084
+ }], locale: [{
1085
+ type: Input
1086
+ }], theme: [{
1087
+ type: Input
1088
+ }], isDarkMode: [{
1089
+ type: HostBinding,
1090
+ args: ['class.dark-theme']
1091
+ }], disabledState: [{
1092
+ type: Input
1093
+ }], valueChange: [{
1094
+ type: Output
1095
+ }], action: [{
1096
+ type: Output
1097
+ }], minDate: [{
1098
+ type: Input
1099
+ }], maxDate: [{
1100
+ type: Input
1101
+ }], ranges: [{
1102
+ type: Input
1103
+ }], onDocumentClick: [{
1104
+ type: HostListener,
1105
+ args: ['document:click', ['$event']]
1106
+ }] } });
1107
+
1108
+ /*
1109
+ * Public API Surface of ngxsmk-datepicker
1110
+ */
1111
+
1112
+ /**
1113
+ * Generated bundle index. Do not edit.
1114
+ */
1115
+
1116
+ export { CustomSelectComponent, NgxsmkDatepickerComponent, addMonths, generateMonthOptions, generateTimeOptions, generateWeekDays, generateYearOptions, get24Hour, getEndOfDay, getEndOfMonth, getFirstDayOfWeek, getStartOfDay, getStartOfMonth, isSameDay, normalizeDate, processDateRanges, subtractDays, update12HourState };
1117
+ //# sourceMappingURL=ngxsmk-datepicker.mjs.map