ngxsmk-datepicker 1.3.4 → 1.3.6

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,35 @@
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 } 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
6
 
7
+ function getStartOfDay(d) {
8
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 0, 0, 0, 0);
9
+ }
10
+ function getEndOfDay(d) {
11
+ return new Date(d.getFullYear(), d.getMonth(), d.getDate(), 23, 59, 59, 999);
12
+ }
13
+ function addMonths(d, months) {
14
+ const newDate = new Date(d);
15
+ newDate.setMonth(d.getMonth() + months);
16
+ return newDate;
17
+ }
18
+ function subtractDays(d, days) {
19
+ const newDate = new Date(d);
20
+ newDate.setDate(d.getDate() - days);
21
+ return newDate;
22
+ }
23
+ function getStartOfMonth(d) {
24
+ return new Date(d.getFullYear(), d.getMonth(), 1);
25
+ }
26
+ function getEndOfMonth(d) {
27
+ return new Date(d.getFullYear(), d.getMonth() + 1, 0);
28
+ }
7
29
  class CustomSelectComponent {
8
30
  constructor() {
9
31
  this.options = [];
32
+ this.disabled = false;
10
33
  this.valueChange = new EventEmitter();
11
34
  this.isOpen = false;
12
35
  this.elementRef = inject(ElementRef);
@@ -20,6 +43,8 @@ class CustomSelectComponent {
20
43
  return selectedOption ? selectedOption.label : '';
21
44
  }
22
45
  toggleDropdown() {
46
+ if (this.disabled)
47
+ return;
23
48
  this.isOpen = !this.isOpen;
24
49
  }
25
50
  selectOption(option) {
@@ -28,9 +53,9 @@ class CustomSelectComponent {
28
53
  this.isOpen = false;
29
54
  }
30
55
  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: `
56
+ 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", disabled: "disabled" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
32
57
  <div class="ngxsmk-select-container" (click)="toggleDropdown()">
33
- <button type="button" class="ngxsmk-select-display">
58
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
34
59
  <span>{{ displayValue }}</span>
35
60
  <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
36
61
  <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
@@ -49,13 +74,13 @@ class CustomSelectComponent {
49
74
  </div>
50
75
  }
51
76
  </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 }] }); }
77
+ `, 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
78
  }
54
79
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, decorators: [{
55
80
  type: Component,
56
81
  args: [{ selector: 'app-custom-select', standalone: true, imports: [CommonModule], template: `
57
82
  <div class="ngxsmk-select-container" (click)="toggleDropdown()">
58
- <button type="button" class="ngxsmk-select-display">
83
+ <button type="button" class="ngxsmk-select-display" [disabled]="disabled">
59
84
  <span>{{ displayValue }}</span>
60
85
  <svg class="ngxsmk-arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
61
86
  <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
@@ -74,11 +99,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
74
99
  </div>
75
100
  }
76
101
  </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"] }]
102
+ `, 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
103
  }], propDecorators: { options: [{
79
104
  type: Input
80
105
  }], value: [{
81
106
  type: Input
107
+ }], disabled: [{
108
+ type: Input
82
109
  }], valueChange: [{
83
110
  type: Output
84
111
  }], onDocumentClick: [{
@@ -92,19 +119,31 @@ class NgxsmkDatepickerComponent {
92
119
  this.showRanges = true;
93
120
  this.showTime = false;
94
121
  this.minuteInterval = 1;
95
- this.value = null;
122
+ // NEW: Holiday Provider Inputs
123
+ this.holidayProvider = null;
124
+ this.disableHolidays = false;
125
+ // Popover/Input Mode
126
+ this.placeholder = 'Select Date';
127
+ this.inline = false;
128
+ this.isCalendarOpen = false;
129
+ this._internalValue = null;
96
130
  this._startAtDate = null;
97
131
  this._locale = 'en-US';
98
132
  this.theme = 'light';
133
+ this.onChange = (_) => { };
134
+ this.onTouched = () => { };
135
+ this.disabled = false;
99
136
  this.valueChange = new EventEmitter();
137
+ this.action = new EventEmitter();
100
138
  this._minDate = null;
101
139
  this._maxDate = null;
102
140
  this._ranges = null;
103
141
  this.currentDate = new Date();
104
142
  this.daysInMonth = [];
105
143
  this.weekDays = [];
106
- this.today = new Date();
144
+ this.today = getStartOfDay(new Date());
107
145
  this.selectedDate = null;
146
+ this.selectedDates = [];
108
147
  this.startDate = null;
109
148
  this.endDate = null;
110
149
  this.hoveredDate = null;
@@ -124,11 +163,16 @@ class NgxsmkDatepickerComponent {
124
163
  { label: 'AM', value: false },
125
164
  { label: 'PM', value: true }
126
165
  ];
166
+ // Animation state properties
167
+ this.animateForward = false;
168
+ this.animateBackward = false;
169
+ this.elementRef = inject(ElementRef);
127
170
  }
128
171
  set startAt(value) { this._startAtDate = this._normalizeDate(value); }
129
172
  set locale(value) { this._locale = value; }
130
173
  get locale() { return this._locale; }
131
174
  get isDarkMode() { return this.theme === 'dark'; }
175
+ set disabledState(isDisabled) { this.disabled = isDisabled; }
132
176
  set minDate(value) { this._minDate = this._normalizeDate(value); }
133
177
  set maxDate(value) { this._maxDate = this._normalizeDate(value); }
134
178
  set ranges(value) {
@@ -146,30 +190,114 @@ class NgxsmkDatepickerComponent {
146
190
  }
147
191
  this.updateRangesArray();
148
192
  }
193
+ get isInlineMode() {
194
+ return this.inline === true || this.inline === 'always' ||
195
+ (this.inline === 'auto' && typeof window !== 'undefined' && window.matchMedia('(min-width: 768px)').matches);
196
+ }
197
+ get isCalendarVisible() {
198
+ return this.isInlineMode || this.isCalendarOpen;
199
+ }
200
+ get displayValue() {
201
+ if (this.mode === 'single' && this.selectedDate) {
202
+ return this.selectedDate.toLocaleString(this.locale, {
203
+ year: 'numeric', month: 'short', day: '2-digit',
204
+ hour: this.showTime ? '2-digit' : undefined,
205
+ minute: this.showTime ? '2-digit' : undefined
206
+ });
207
+ }
208
+ else if (this.mode === 'range' && this.startDate && this.endDate) {
209
+ const start = this.startDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
210
+ const end = this.endDate.toLocaleString(this.locale, { year: 'numeric', month: 'short', day: '2-digit' });
211
+ return `${start} - ${end}`;
212
+ }
213
+ else if (this.mode === 'multiple' && this.selectedDates.length > 0) {
214
+ return `${this.selectedDates.length} dates selected`;
215
+ }
216
+ return '';
217
+ }
218
+ onDocumentClick(event) {
219
+ if (!this.isInlineMode && this.isCalendarOpen && !this.elementRef.nativeElement.contains(event.target)) {
220
+ this.isCalendarOpen = false;
221
+ }
222
+ }
223
+ writeValue(val) {
224
+ this._internalValue = val;
225
+ this.initializeValue(val);
226
+ this.generateCalendar();
227
+ }
228
+ registerOnChange(fn) {
229
+ this.onChange = fn;
230
+ }
231
+ registerOnTouched(fn) {
232
+ this.onTouched = fn;
233
+ }
234
+ setDisabledState(isDisabled) {
235
+ this.disabled = isDisabled;
236
+ }
237
+ emitValue(val) {
238
+ this._internalValue = val;
239
+ this.valueChange.emit(val);
240
+ this.onChange(val);
241
+ this.onTouched();
242
+ // Auto-close popover when a selection is complete
243
+ if (!this.isInlineMode && val !== null) {
244
+ if (this.mode === 'single' || (this.mode === 'range' && this.startDate && this.endDate)) {
245
+ this.isCalendarOpen = false;
246
+ }
247
+ }
248
+ }
249
+ toggleCalendar() {
250
+ if (this.disabled || this.isInlineMode)
251
+ return;
252
+ this.isCalendarOpen = !this.isCalendarOpen;
253
+ }
254
+ clearValue(event) {
255
+ if (event)
256
+ event.stopPropagation();
257
+ if (this.disabled)
258
+ return;
259
+ this.selectedDate = null;
260
+ this.selectedDates = [];
261
+ this.startDate = null;
262
+ this.endDate = null;
263
+ this.hoveredDate = null;
264
+ this.isCalendarOpen = false;
265
+ this.emitValue(null);
266
+ this.action.emit({ type: 'clear', payload: null });
267
+ // Reset view to today after clearing
268
+ this.currentDate = new Date();
269
+ this._currentMonth = this.currentDate.getMonth();
270
+ this._currentYear = this.currentDate.getFullYear();
271
+ this.generateCalendar();
272
+ }
149
273
  get currentMonth() { return this._currentMonth; }
150
274
  set currentMonth(month) {
275
+ if (this.disabled)
276
+ return;
151
277
  if (this._currentMonth !== month) {
152
278
  this._currentMonth = month;
153
279
  this.currentDate.setMonth(month);
154
- this.generateCalendar();
280
+ this.generateCalendar(true);
155
281
  }
156
282
  }
157
283
  get currentYear() { return this._currentYear; }
158
284
  set currentYear(year) {
285
+ if (this.disabled)
286
+ return;
159
287
  if (this._currentYear !== year) {
160
288
  this._currentYear = year;
161
289
  this.currentDate.setFullYear(year);
162
- this.generateCalendar();
290
+ this.generateCalendar(true);
163
291
  }
164
292
  }
165
293
  ngOnInit() {
166
- if (this._locale === 'en-US') {
294
+ if (this._locale === 'en-US' && typeof navigator !== 'undefined') {
167
295
  this._locale = navigator.language;
168
296
  }
169
297
  this.today.setHours(0, 0, 0, 0);
170
298
  this.generateLocaleData();
171
299
  this.generateTimeOptions();
172
- if (this.showTime && !this.value) {
300
+ if (this.showTime && !this._internalValue) {
173
301
  const now = new Date();
174
302
  this.currentHour = now.getHours();
175
303
  this.currentMinute = Math.floor(now.getMinutes() / this.minuteInterval) * this.minuteInterval;
@@ -179,8 +307,8 @@ class NgxsmkDatepickerComponent {
179
307
  }
180
308
  this.update12HourState(this.currentHour);
181
309
  }
182
- if (this.value) {
183
- this.initializeValue(this.value);
310
+ if (this._internalValue) {
311
+ this.initializeValue(this._internalValue);
184
312
  }
185
313
  else if (this._startAtDate) {
186
314
  this.initializeValue(null);
@@ -198,11 +326,14 @@ class NgxsmkDatepickerComponent {
198
326
  this.onTimeChange();
199
327
  }
200
328
  if (changes['value'] && changes['value'].currentValue !== changes['value'].previousValue) {
201
- this.initializeValue(changes['value'].currentValue);
329
+ this.writeValue(changes['value'].currentValue);
330
+ }
331
+ // Rerun calendar generation if provider changes to refresh disabled states
332
+ if (changes['holidayProvider'] || changes['disableHolidays']) {
202
333
  this.generateCalendar();
203
334
  }
204
335
  if (changes['startAt']) {
205
- if (!this.value && this._startAtDate) {
336
+ if (!this._internalValue && this._startAtDate) {
206
337
  this.currentDate = new Date(this._startAtDate);
207
338
  this._currentMonth = this.currentDate.getMonth();
208
339
  this._currentYear = this.currentDate.getFullYear();
@@ -227,6 +358,10 @@ class NgxsmkDatepickerComponent {
227
358
  }
228
359
  initializeValue(value) {
229
360
  let initialDate = null;
361
+ this.selectedDate = null;
362
+ this.startDate = null;
363
+ this.endDate = null;
364
+ this.selectedDates = [];
230
365
  if (value) {
231
366
  if (this.mode === 'single' && value instanceof Date) {
232
367
  this.selectedDate = this._normalizeDate(value);
@@ -237,11 +372,10 @@ class NgxsmkDatepickerComponent {
237
372
  this.endDate = this._normalizeDate(value.end);
238
373
  initialDate = this.startDate;
239
374
  }
240
- }
241
- else {
242
- this.selectedDate = null;
243
- this.startDate = null;
244
- this.endDate = null;
375
+ else if (this.mode === 'multiple' && Array.isArray(value)) {
376
+ this.selectedDates = value.map(d => this._normalizeDate(d)).filter((d) => d !== null);
377
+ initialDate = this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
378
+ }
245
379
  }
246
380
  const viewCenterDate = initialDate || this._startAtDate || new Date();
247
381
  if (viewCenterDate) {
@@ -257,7 +391,7 @@ class NgxsmkDatepickerComponent {
257
391
  _normalizeDate(date) {
258
392
  if (!date)
259
393
  return null;
260
- const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date);
394
+ const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date.toDate ? date.toDate() : date);
261
395
  if (isNaN(d.getTime()))
262
396
  return null;
263
397
  return d;
@@ -298,60 +432,99 @@ class NgxsmkDatepickerComponent {
298
432
  this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({ key, value })) : [];
299
433
  }
300
434
  selectRange(range) {
435
+ if (this.disabled)
436
+ return;
301
437
  this.startDate = this.applyCurrentTime(range[0]);
302
438
  this.endDate = this.applyCurrentTime(range[1]);
303
439
  if (this.startDate && this.endDate) {
304
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
440
+ this.emitValue({ start: this.startDate, end: this.endDate });
305
441
  }
306
442
  this.currentDate = new Date(this.startDate);
307
443
  this.initializeValue({ start: this.startDate, end: this.endDate });
308
444
  this.generateCalendar();
445
+ this.action.emit({ type: 'rangeSelected', payload: { start: this.startDate, end: this.endDate, key: this.rangesArray.find(r => r.value === range)?.key } });
446
+ }
447
+ // NEW: Check if a date is a holiday
448
+ isHoliday(date) {
449
+ if (!date || !this.holidayProvider)
450
+ return false;
451
+ const dateOnly = getStartOfDay(date);
452
+ return this.holidayProvider.isHoliday(dateOnly);
453
+ }
454
+ // NEW: Get holiday label
455
+ getHolidayLabel(date) {
456
+ if (!date || !this.holidayProvider || !this.isHoliday(date))
457
+ return null;
458
+ return this.holidayProvider.getHolidayLabel ? this.holidayProvider.getHolidayLabel(getStartOfDay(date)) : 'Holiday';
309
459
  }
310
460
  isDateDisabled(date) {
311
461
  if (!date)
312
462
  return false;
313
- const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
463
+ const dateOnly = getStartOfDay(date);
464
+ // 1. Check holiday provider for disabling
465
+ if (this.holidayProvider && this.disableHolidays && this.holidayProvider.isHoliday(dateOnly)) {
466
+ return true;
467
+ }
468
+ // 2. Check min/max date
314
469
  if (this._minDate) {
315
- const minDateOnly = new Date(this._minDate.getFullYear(), this._minDate.getMonth(), this._minDate.getDate());
316
- if (dateOnly < minDateOnly)
470
+ const minDateOnly = getStartOfDay(this._minDate);
471
+ if (dateOnly.getTime() < minDateOnly.getTime())
317
472
  return true;
318
473
  }
319
474
  if (this._maxDate) {
320
- const maxDateOnly = new Date(this._maxDate.getFullYear(), this._maxDate.getMonth(), this._maxDate.getDate());
321
- if (dateOnly > maxDateOnly)
475
+ const maxDateOnly = getStartOfDay(this._maxDate);
476
+ if (dateOnly.getTime() > maxDateOnly.getTime())
322
477
  return true;
323
478
  }
479
+ // 3. Check custom invalid date function
324
480
  return this.isInvalidDate(date);
325
481
  }
482
+ isMultipleSelected(d) {
483
+ if (!d || this.mode !== 'multiple')
484
+ return false;
485
+ const dTime = getStartOfDay(d).getTime();
486
+ return this.selectedDates.some(selected => getStartOfDay(selected).getTime() === dTime);
487
+ }
326
488
  onTimeChange() {
489
+ if (this.disabled)
490
+ return;
327
491
  if (this.mode === 'single' && this.selectedDate) {
328
492
  this.selectedDate = this.applyCurrentTime(this.selectedDate);
329
- this.valueChange.emit(this.selectedDate);
493
+ this.emitValue(this.selectedDate);
330
494
  }
331
495
  else if (this.mode === 'range' && this.startDate && this.endDate) {
332
496
  this.startDate = this.applyCurrentTime(this.startDate);
333
497
  this.endDate = this.applyCurrentTime(this.endDate);
334
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
498
+ this.emitValue({ start: this.startDate, end: this.endDate });
335
499
  }
336
500
  else if (this.mode === 'range' && this.startDate && !this.endDate) {
337
501
  this.startDate = this.applyCurrentTime(this.startDate);
338
502
  }
503
+ else if (this.mode === 'multiple') {
504
+ this.selectedDates = this.selectedDates.map(date => {
505
+ const newDate = getStartOfDay(date);
506
+ return this.applyCurrentTime(newDate);
507
+ });
508
+ this.emitValue([...this.selectedDates]);
509
+ }
510
+ this.action.emit({ type: 'timeChanged', payload: { hour: this.currentHour, minute: this.currentMinute } });
339
511
  }
340
512
  onDateClick(day) {
341
- if (!day || this.isDateDisabled(day))
513
+ if (!day || this.isDateDisabled(day) || this.disabled)
342
514
  return;
515
+ const dateToToggle = getStartOfDay(day);
343
516
  if (this.mode === 'single') {
344
517
  this.selectedDate = this.applyCurrentTime(day);
345
- this.valueChange.emit(this.selectedDate);
518
+ this.emitValue(this.selectedDate);
346
519
  }
347
- else {
520
+ else if (this.mode === 'range') {
348
521
  if (!this.startDate || (this.startDate && this.endDate)) {
349
522
  this.startDate = this.applyCurrentTime(day);
350
523
  this.endDate = null;
351
524
  }
352
525
  else if (day >= this.startDate) {
353
526
  this.endDate = this.applyCurrentTime(day);
354
- this.valueChange.emit({ start: this.startDate, end: this.endDate });
527
+ this.emitValue({ start: this.startDate, end: this.endDate });
355
528
  }
356
529
  else {
357
530
  this.startDate = this.applyCurrentTime(day);
@@ -359,14 +532,33 @@ class NgxsmkDatepickerComponent {
359
532
  }
360
533
  this.hoveredDate = null;
361
534
  }
362
- if (this.mode === 'single' && this.selectedDate) {
363
- this.update12HourState(this.selectedDate.getHours());
364
- this.currentMinute = this.selectedDate.getMinutes();
365
- }
366
- else if (this.mode === 'range' && this.startDate) {
367
- this.update12HourState(this.startDate.getHours());
368
- this.currentMinute = this.startDate.getMinutes();
369
- }
535
+ else if (this.mode === 'multiple') {
536
+ const existingIndex = this.selectedDates.findIndex(d => this.isSameDay(d, dateToToggle));
537
+ if (existingIndex > -1) {
538
+ this.selectedDates.splice(existingIndex, 1);
539
+ }
540
+ else {
541
+ const dateWithTime = this.applyCurrentTime(dateToToggle);
542
+ this.selectedDates.push(dateWithTime);
543
+ this.selectedDates.sort((a, b) => a.getTime() - b.getTime());
544
+ }
545
+ this.emitValue([...this.selectedDates]);
546
+ }
547
+ const dateToSync = this.mode === 'single' ? this.selectedDate :
548
+ this.mode === 'range' ? this.startDate :
549
+ this.mode === 'multiple' && this.selectedDates.length > 0 ? this.selectedDates[this.selectedDates.length - 1] : null;
550
+ if (dateToSync) {
551
+ this.update12HourState(dateToSync.getHours());
552
+ this.currentMinute = dateToSync.getMinutes();
553
+ }
554
+ this.action.emit({
555
+ type: 'dateSelected',
556
+ payload: {
557
+ mode: this.mode,
558
+ value: this._internalValue,
559
+ date: day
560
+ }
561
+ });
370
562
  }
371
563
  onDateHover(day) {
372
564
  if (this.mode === 'range' && this.startDate && !this.endDate && day) {
@@ -376,12 +568,12 @@ class NgxsmkDatepickerComponent {
376
568
  isPreviewInRange(day) {
377
569
  if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day)
378
570
  return false;
379
- const start = this.startDate.getTime();
380
- const end = this.hoveredDate.getTime();
381
- const time = day.getTime();
571
+ const start = getStartOfDay(this.startDate).getTime();
572
+ const end = getStartOfDay(this.hoveredDate).getTime();
573
+ const time = getStartOfDay(day).getTime();
382
574
  return time > Math.min(start, end) && time < Math.max(start, end);
383
575
  }
384
- generateCalendar() {
576
+ generateCalendar(resetAnimation = true) {
385
577
  this.daysInMonth = [];
386
578
  const year = this.currentDate.getFullYear();
387
579
  const month = this.currentDate.getMonth();
@@ -398,6 +590,18 @@ class NgxsmkDatepickerComponent {
398
590
  for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
399
591
  this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));
400
592
  }
593
+ if (resetAnimation) {
594
+ this.animateForward = false;
595
+ this.animateBackward = false;
596
+ }
597
+ this.action.emit({
598
+ type: 'calendarGenerated',
599
+ payload: {
600
+ month: month,
601
+ year: year,
602
+ days: this.daysInMonth.filter(d => d !== null)
603
+ }
604
+ });
401
605
  }
402
606
  generateDropdownOptions() {
403
607
  const startYear = this._currentYear - 10;
@@ -408,8 +612,31 @@ class NgxsmkDatepickerComponent {
408
612
  }
409
613
  }
410
614
  changeMonth(delta) {
411
- this.currentDate.setMonth(this.currentDate.getMonth() + delta);
412
- this.generateCalendar();
615
+ if (this.disabled)
616
+ return;
617
+ // 1. Set the animation class (triggers slide-out)
618
+ if (delta > 0) {
619
+ this.animateForward = true;
620
+ this.animateBackward = false;
621
+ }
622
+ else {
623
+ this.animateBackward = true;
624
+ this.animateForward = false;
625
+ }
626
+ const newDate = addMonths(this.currentDate, delta);
627
+ // 2. Wait for the slide-out transition to complete (300ms)
628
+ setTimeout(() => {
629
+ // 3. Update the data
630
+ this.currentDate = newDate;
631
+ this._currentMonth = newDate.getMonth();
632
+ this._currentYear = newDate.getFullYear();
633
+ // Generate new calendar view but tell it *not* to reset animation flags yet.
634
+ this.generateCalendar(false);
635
+ // 4. Reset the animation flags to false (triggers slide-in of the new content)
636
+ this.animateForward = false;
637
+ this.animateBackward = false;
638
+ }, 300); // Wait time should match the CSS transition duration (0.3s)
639
+ this.action.emit({ type: 'monthChanged', payload: { delta: delta } });
413
640
  }
414
641
  isSameDay(d1, d2) {
415
642
  if (!d1 || !d2)
@@ -421,183 +648,263 @@ class NgxsmkDatepickerComponent {
421
648
  isInRange(d) {
422
649
  if (!d || !this.startDate || !this.endDate)
423
650
  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();
651
+ const dTime = getStartOfDay(d).getTime();
652
+ const startDayTime = getStartOfDay(this.startDate).getTime();
653
+ const endDayTime = getStartOfDay(this.endDate).getTime();
427
654
  const startTime = Math.min(startDayTime, endDayTime);
428
655
  const endTime = Math.max(startDayTime, endDayTime);
429
656
  return dTime > startTime && dTime < endTime;
430
657
  }
431
658
  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>
659
+ 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: [{
660
+ provide: NG_VALUE_ACCESSOR,
661
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
662
+ multi: true
663
+ }], usesOnChanges: true, ngImport: i0, template: `
664
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
665
+ @if (!isInlineMode) {
666
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
667
+ <input type="text"
668
+ [value]="displayValue"
669
+ [placeholder]="placeholder"
670
+ readonly
671
+ [disabled]="disabled"
672
+ class="ngxsmk-display-input">
673
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
674
+ <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>
675
+ </button>
441
676
  </div>
442
677
  }
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
- }
678
+
679
+ @if (isCalendarVisible) {
680
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
681
+ <div class="ngxsmk-datepicker-container">
682
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
683
+ <div class="ngxsmk-ranges-container">
684
+ <ul>
685
+ @for (range of rangesArray; track range.key) {
686
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
687
+ }
688
+ </ul>
482
689
  </div>
483
690
  }
484
- </div>
485
- </div>
691
+ <div class="ngxsmk-calendar-container">
692
+ <div class="ngxsmk-header">
693
+ <div class="ngxsmk-month-year-selects">
694
+ <app-custom-select class="month-select" [options]="monthOptions"
695
+ [(value)]="currentMonth" [disabled]="disabled"></app-custom-select>
696
+ <app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></app-custom-select>
697
+ </div>
698
+ <div class="ngxsmk-nav-buttons">
699
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled">
700
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
701
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
702
+ d="M328 112L184 256l144 144"/>
703
+ </svg>
704
+ </button>
705
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
706
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
707
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
708
+ d="M184 112l144 144-144 144"/>
709
+ </svg>
710
+ </button>
711
+ </div>
712
+ </div>
713
+ <div class="ngxsmk-days-grid-wrapper">
714
+ <div class="ngxsmk-days-grid"
715
+ [class.animate-forward]="animateForward"
716
+ [class.animate-backward]="animateBackward">
717
+ @for (day of weekDays; track day) {
718
+ <div class="ngxsmk-day-name">{{ day }}</div>
719
+ }
720
+ @for (day of daysInMonth; track $index) {
721
+ <div class="ngxsmk-day-cell"
722
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
723
+ [class.today]="isSameDay(day, today)"
724
+ [class.holiday]="isHoliday(day)"
725
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
726
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
727
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
728
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
729
+ [class.in-range]="mode === 'range' && isInRange(day)"
730
+ [class.preview-range]="isPreviewInRange(day)"
731
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
732
+ @if (day) {
733
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
734
+ }
735
+ </div>
736
+ }
737
+ </div>
738
+ </div>
486
739
 
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>
740
+ @if (showTime) {
741
+ <div class="ngxsmk-time-selection">
742
+ <span class="ngxsmk-time-label">Time:</span>
743
+ <app-custom-select
744
+ class="hour-select"
745
+ [options]="hourOptions"
746
+ [(value)]="currentDisplayHour"
747
+ (valueChange)="onTimeChange()"
748
+ [disabled]="disabled"
749
+ ></app-custom-select>
750
+ <span class="ngxsmk-time-separator">:</span>
751
+ <app-custom-select
752
+ class="minute-select"
753
+ [options]="minuteOptions"
754
+ [(value)]="currentMinute"
755
+ (valueChange)="onTimeChange()"
756
+ [disabled]="disabled"
757
+ ></app-custom-select>
758
+ <app-custom-select
759
+ class="ampm-select"
760
+ [options]="ampmOptions"
761
+ [(value)]="isPm"
762
+ (valueChange)="onTimeChange()"
763
+ [disabled]="disabled"
764
+ ></app-custom-select>
765
+ </div>
766
+ }
767
+
768
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
769
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
770
+ Clear
771
+ </button>
772
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
773
+ Close
774
+ </button>
775
+ </div>
776
+ </div>
509
777
  </div>
510
- }
511
-
512
- </div>
778
+ </div>
779
+ }
513
780
  </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}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:16px;background:var(--datepicker-background)}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;position:relative;z-index:2;gap:5px}.ngxsmk-month-year-selects{display:flex;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-buttons{display:flex}.ngxsmk-nav-button{background:none;border:none;padding:8px;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-nav-button:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-days-grid-wrapper{position:relative}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-weight:600;font-size:.8rem;color:var(--datepicker-subtle-text-color);padding:8px 0}.ngxsmk-day-cell{position:relative;height:38px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-number{width:36px;height:36px;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{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);background:var(--datepicker-background)}.ngxsmk-ranges-container ul{list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border-radius:6px;cursor:pointer;color:var(--datepicker-text-color)}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-time-selection{display:flex;align-items:center;justify-content:center;gap:4px;margin-top:16px;padding-top:12px;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-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}.ngxsmk-time-separator{font-weight:600;font-size:1.1rem;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" }] }); }
781
+ `, 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: "app-custom-select", inputs: ["options", "value", "disabled"], outputs: ["valueChange"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
515
782
  }
516
783
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, decorators: [{
517
784
  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>
785
+ args: [{ selector: 'ngxsmk-datepicker', standalone: true, imports: [CommonModule, FormsModule, CustomSelectComponent, DatePipe, ReactiveFormsModule], providers: [{
786
+ provide: NG_VALUE_ACCESSOR,
787
+ useExisting: forwardRef(() => NgxsmkDatepickerComponent),
788
+ multi: true
789
+ }], template: `
790
+ <div class="ngxsmk-datepicker-wrapper" [class.ngxsmk-inline-mode]="isInlineMode">
791
+ @if (!isInlineMode) {
792
+ <div class="ngxsmk-input-group" (click)="toggleCalendar()" [class.disabled]="disabled">
793
+ <input type="text"
794
+ [value]="displayValue"
795
+ [placeholder]="placeholder"
796
+ readonly
797
+ [disabled]="disabled"
798
+ class="ngxsmk-display-input">
799
+ <button type="button" class="ngxsmk-clear-button" (click)="clearValue($event)" [disabled]="disabled" *ngIf="displayValue">
800
+ <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>
801
+ </button>
527
802
  </div>
528
803
  }
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
- }
804
+
805
+ @if (isCalendarVisible) {
806
+ <div class="ngxsmk-popover-container" [class.ngxsmk-inline-container]="isInlineMode">
807
+ <div class="ngxsmk-datepicker-container">
808
+ @if (showRanges && rangesArray.length > 0 && mode === 'range') {
809
+ <div class="ngxsmk-ranges-container">
810
+ <ul>
811
+ @for (range of rangesArray; track range.key) {
812
+ <li (click)="selectRange(range.value)" [class.disabled]="disabled">{{ range.key }}</li>
813
+ }
814
+ </ul>
568
815
  </div>
569
816
  }
570
- </div>
571
- </div>
817
+ <div class="ngxsmk-calendar-container">
818
+ <div class="ngxsmk-header">
819
+ <div class="ngxsmk-month-year-selects">
820
+ <app-custom-select class="month-select" [options]="monthOptions"
821
+ [(value)]="currentMonth" [disabled]="disabled"></app-custom-select>
822
+ <app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear" [disabled]="disabled"></app-custom-select>
823
+ </div>
824
+ <div class="ngxsmk-nav-buttons">
825
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(-1)" [disabled]="disabled">
826
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
827
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
828
+ d="M328 112L184 256l144 144"/>
829
+ </svg>
830
+ </button>
831
+ <button type="button" class="ngxsmk-nav-button" (click)="changeMonth(1)" [disabled]="disabled">
832
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
833
+ <path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
834
+ d="M184 112l144 144-144 144"/>
835
+ </svg>
836
+ </button>
837
+ </div>
838
+ </div>
839
+ <div class="ngxsmk-days-grid-wrapper">
840
+ <div class="ngxsmk-days-grid"
841
+ [class.animate-forward]="animateForward"
842
+ [class.animate-backward]="animateBackward">
843
+ @for (day of weekDays; track day) {
844
+ <div class="ngxsmk-day-name">{{ day }}</div>
845
+ }
846
+ @for (day of daysInMonth; track $index) {
847
+ <div class="ngxsmk-day-cell"
848
+ [class.empty]="!day" [class.disabled]="isDateDisabled(day)"
849
+ [class.today]="isSameDay(day, today)"
850
+ [class.holiday]="isHoliday(day)"
851
+ [class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
852
+ [class.multiple-selected]="mode === 'multiple' && isMultipleSelected(day)"
853
+ [class.start-date]="mode === 'range' && isSameDay(day, startDate)"
854
+ [class.end-date]="mode === 'range' && isSameDay(day, endDate)"
855
+ [class.in-range]="mode === 'range' && isInRange(day)"
856
+ [class.preview-range]="isPreviewInRange(day)"
857
+ (click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
858
+ @if (day) {
859
+ <div class="ngxsmk-day-number" [attr.title]="getHolidayLabel(day)">{{ day | date : 'd' }}</div>
860
+ }
861
+ </div>
862
+ }
863
+ </div>
864
+ </div>
572
865
 
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>
866
+ @if (showTime) {
867
+ <div class="ngxsmk-time-selection">
868
+ <span class="ngxsmk-time-label">Time:</span>
869
+ <app-custom-select
870
+ class="hour-select"
871
+ [options]="hourOptions"
872
+ [(value)]="currentDisplayHour"
873
+ (valueChange)="onTimeChange()"
874
+ [disabled]="disabled"
875
+ ></app-custom-select>
876
+ <span class="ngxsmk-time-separator">:</span>
877
+ <app-custom-select
878
+ class="minute-select"
879
+ [options]="minuteOptions"
880
+ [(value)]="currentMinute"
881
+ (valueChange)="onTimeChange()"
882
+ [disabled]="disabled"
883
+ ></app-custom-select>
884
+ <app-custom-select
885
+ class="ampm-select"
886
+ [options]="ampmOptions"
887
+ [(value)]="isPm"
888
+ (valueChange)="onTimeChange()"
889
+ [disabled]="disabled"
890
+ ></app-custom-select>
891
+ </div>
892
+ }
893
+
894
+ <div class="ngxsmk-footer" *ngIf="!isInlineMode">
895
+ <button type="button" class="ngxsmk-clear-button-footer" (click)="clearValue($event)" [disabled]="disabled">
896
+ Clear
897
+ </button>
898
+ <button type="button" class="ngxsmk-close-button" (click)="isCalendarOpen = false" [disabled]="disabled">
899
+ Close
900
+ </button>
901
+ </div>
902
+ </div>
595
903
  </div>
596
- }
597
-
598
- </div>
904
+ </div>
905
+ }
599
906
  </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}.ngxsmk-calendar-container{font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border-radius:10px;padding:16px;background:var(--datepicker-background)}.ngxsmk-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;position:relative;z-index:2;gap:5px}.ngxsmk-month-year-selects{display:flex;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-buttons{display:flex}.ngxsmk-nav-button{background:none;border:none;padding:8px;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.ngxsmk-nav-button:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-nav-button svg{width:18px;height:18px}.ngxsmk-days-grid-wrapper{position:relative}.ngxsmk-days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.ngxsmk-day-name{font-weight:600;font-size:.8rem;color:var(--datepicker-subtle-text-color);padding:8px 0}.ngxsmk-day-cell{position:relative;height:38px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.ngxsmk-day-number{width:36px;height:36px;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{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);background:var(--datepicker-background)}.ngxsmk-ranges-container ul{list-style:none;padding:0;margin:0}.ngxsmk-ranges-container li{padding:10px;margin-bottom:8px;border-radius:6px;cursor:pointer;color:var(--datepicker-text-color)}.ngxsmk-ranges-container li:hover{background-color:var(--datepicker-hover-background)}.ngxsmk-time-selection{display:flex;align-items:center;justify-content:center;gap:4px;margin-top:16px;padding-top:12px;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-selection app-custom-select{--custom-select-width: 60px;height:30px}.ngxsmk-time-selection app-custom-select.ampm-select{--custom-select-width: 70px}.ngxsmk-time-separator{font-weight:600;font-size:1.1rem;color:var(--datepicker-text-color)}\n"] }]
907
+ `, 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
908
  }], propDecorators: { mode: [{
602
909
  type: Input
603
910
  }], isInvalidDate: [{
@@ -608,7 +915,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
608
915
  type: Input
609
916
  }], minuteInterval: [{
610
917
  type: Input
611
- }], value: [{
918
+ }], holidayProvider: [{
919
+ type: Input
920
+ }], disableHolidays: [{
921
+ type: Input
922
+ }], placeholder: [{
923
+ type: Input
924
+ }], inline: [{
612
925
  type: Input
613
926
  }], startAt: [{
614
927
  type: Input
@@ -619,14 +932,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
619
932
  }], isDarkMode: [{
620
933
  type: HostBinding,
621
934
  args: ['class.dark-theme']
935
+ }], disabledState: [{
936
+ type: Input
622
937
  }], valueChange: [{
623
938
  type: Output
939
+ }], action: [{
940
+ type: Output
624
941
  }], minDate: [{
625
942
  type: Input
626
943
  }], maxDate: [{
627
944
  type: Input
628
945
  }], ranges: [{
629
946
  type: Input
947
+ }], onDocumentClick: [{
948
+ type: HostListener,
949
+ args: ['document:click', ['$event']]
630
950
  }] } });
631
951
 
632
952
  /*