ngxsmk-datepicker 1.2.2 → 1.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngxsmk-datepicker.mjs +44 -120
- package/fesm2022/ngxsmk-datepicker.mjs.map +1 -1
- package/index.d.ts +2 -43
- package/package.json +1 -1
|
@@ -1,42 +1,33 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter, HostListener, Output, Input, Component,
|
|
2
|
+
import { EventEmitter, inject, ElementRef, HostListener, Output, Input, Component, HostBinding } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
|
-
import { CommonModule
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
5
|
import { FormsModule } from '@angular/forms';
|
|
6
6
|
|
|
7
|
-
// #####################################################################
|
|
8
|
-
// ## Reusable Custom Select Component
|
|
9
|
-
// #####################################################################
|
|
10
7
|
class CustomSelectComponent {
|
|
11
|
-
constructor(
|
|
12
|
-
this.elementRef = elementRef;
|
|
13
|
-
/** The list of available options to display in the dropdown. */
|
|
8
|
+
constructor() {
|
|
14
9
|
this.options = [];
|
|
15
|
-
/** Emits the new value when an option is selected. */
|
|
16
10
|
this.valueChange = new EventEmitter();
|
|
17
11
|
this.isOpen = false;
|
|
12
|
+
this.elementRef = inject(ElementRef);
|
|
18
13
|
}
|
|
19
|
-
/** Closes the dropdown when a click occurs outside the component boundary. */
|
|
20
14
|
onDocumentClick(event) {
|
|
21
15
|
if (!this.elementRef.nativeElement.contains(event.target))
|
|
22
16
|
this.isOpen = false;
|
|
23
17
|
}
|
|
24
|
-
/** Gets the display label for the currently selected value. */
|
|
25
18
|
get displayValue() {
|
|
26
19
|
const selectedOption = this.options.find((opt) => opt.value === this.value);
|
|
27
20
|
return selectedOption ? selectedOption.label : '';
|
|
28
21
|
}
|
|
29
|
-
/** Toggles the visibility of the dropdown panel. */
|
|
30
22
|
toggleDropdown() {
|
|
31
23
|
this.isOpen = !this.isOpen;
|
|
32
24
|
}
|
|
33
|
-
/** Handles the selection of a new option. */
|
|
34
25
|
selectOption(option) {
|
|
35
26
|
this.value = option.value;
|
|
36
27
|
this.valueChange.emit(this.value);
|
|
37
28
|
this.isOpen = false;
|
|
38
29
|
}
|
|
39
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, deps: [
|
|
30
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
40
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: `
|
|
41
32
|
<div class="ngxsmk-select-container" (click)="toggleDropdown()">
|
|
42
33
|
<button type="button" class="ngxsmk-select-display">
|
|
@@ -84,7 +75,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
84
75
|
}
|
|
85
76
|
</div>
|
|
86
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"] }]
|
|
87
|
-
}],
|
|
78
|
+
}], propDecorators: { options: [{
|
|
88
79
|
type: Input
|
|
89
80
|
}], value: [{
|
|
90
81
|
type: Input
|
|
@@ -95,58 +86,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
95
86
|
args: ['document:click', ['$event']]
|
|
96
87
|
}] } });
|
|
97
88
|
class NgxsmkDatepickerComponent {
|
|
98
|
-
|
|
99
|
-
set locale(value) {
|
|
100
|
-
this._locale = value;
|
|
101
|
-
}
|
|
102
|
-
get locale() {
|
|
103
|
-
return this._locale;
|
|
104
|
-
}
|
|
105
|
-
get isDarkMode() {
|
|
106
|
-
return this.theme === 'dark';
|
|
107
|
-
}
|
|
108
|
-
/** The earliest selectable date. */
|
|
109
|
-
set minDate(value) {
|
|
110
|
-
this._minDate = this._normalizeDate(value);
|
|
111
|
-
}
|
|
112
|
-
/** The latest selectable date. */
|
|
113
|
-
set maxDate(value) {
|
|
114
|
-
this._maxDate = this._normalizeDate(value);
|
|
115
|
-
}
|
|
116
|
-
/** An object of predefined date ranges for quick selection. */
|
|
117
|
-
set ranges(value) {
|
|
118
|
-
if (!value) {
|
|
119
|
-
this._ranges = null;
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {
|
|
123
|
-
const start = this._normalizeDate(dates[0]);
|
|
124
|
-
const end = this._normalizeDate(dates[1]);
|
|
125
|
-
if (start && end)
|
|
126
|
-
acc[key] = [start, end];
|
|
127
|
-
return acc;
|
|
128
|
-
}, {});
|
|
129
|
-
}
|
|
130
|
-
this.updateRangesArray();
|
|
131
|
-
}
|
|
132
|
-
constructor(platformId) {
|
|
133
|
-
this.platformId = platformId;
|
|
134
|
-
/** Sets the selection mode: 'single' date or 'range' selection. */
|
|
89
|
+
constructor() {
|
|
135
90
|
this.mode = 'single';
|
|
136
|
-
/** A function to programmatically disable specific dates. Returns true if the date should be disabled. */
|
|
137
91
|
this.isInvalidDate = () => false;
|
|
138
|
-
/** If true, displays the predefined ranges panel when in 'range' mode. */
|
|
139
92
|
this.showRanges = true;
|
|
140
|
-
/** If true, displays the time selection controls (hour/minute). */
|
|
141
93
|
this.showTime = false;
|
|
142
|
-
/** Sets the minute selection step/interval (e.g., 5, 15, 30). */
|
|
143
94
|
this.minuteInterval = 1;
|
|
144
|
-
/** The initial selected date or date range. Accepts Date, or { start: Date, end: Date }. */
|
|
145
95
|
this.value = null;
|
|
146
96
|
this._locale = 'en-US';
|
|
147
|
-
/** Controls the visual theme: 'light' or 'dark'. */
|
|
148
97
|
this.theme = 'light';
|
|
149
|
-
/** Emits the newly selected date or date range. */
|
|
150
98
|
this.valueChange = new EventEmitter();
|
|
151
99
|
this._minDate = null;
|
|
152
100
|
this._maxDate = null;
|
|
@@ -160,27 +108,43 @@ class NgxsmkDatepickerComponent {
|
|
|
160
108
|
this.endDate = null;
|
|
161
109
|
this.hoveredDate = null;
|
|
162
110
|
this.rangesArray = [];
|
|
111
|
+
this._currentMonth = this.currentDate.getMonth();
|
|
112
|
+
this._currentYear = this.currentDate.getFullYear();
|
|
163
113
|
this.monthOptions = [];
|
|
164
114
|
this.yearOptions = [];
|
|
165
115
|
this.firstDayOfWeek = 0;
|
|
166
|
-
|
|
167
|
-
this.currentHour = 0; // Internal 24h format (0-23)
|
|
116
|
+
this.currentHour = 0;
|
|
168
117
|
this.currentMinute = 0;
|
|
169
|
-
this.currentDisplayHour = 12;
|
|
170
|
-
this.isPm = false;
|
|
118
|
+
this.currentDisplayHour = 12;
|
|
119
|
+
this.isPm = false;
|
|
171
120
|
this.hourOptions = [];
|
|
172
121
|
this.minuteOptions = [];
|
|
173
122
|
this.ampmOptions = [
|
|
174
123
|
{ label: 'AM', value: false },
|
|
175
124
|
{ label: 'PM', value: true }
|
|
176
125
|
];
|
|
177
|
-
if (isPlatformBrowser(this.platformId)) {
|
|
178
|
-
this._locale = navigator.language;
|
|
179
|
-
}
|
|
180
126
|
}
|
|
181
|
-
|
|
182
|
-
|
|
127
|
+
set locale(value) { this._locale = value; }
|
|
128
|
+
get locale() { return this._locale; }
|
|
129
|
+
get isDarkMode() { return this.theme === 'dark'; }
|
|
130
|
+
set minDate(value) { this._minDate = this._normalizeDate(value); }
|
|
131
|
+
set maxDate(value) { this._maxDate = this._normalizeDate(value); }
|
|
132
|
+
set ranges(value) {
|
|
133
|
+
if (!value) {
|
|
134
|
+
this._ranges = null;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {
|
|
138
|
+
const start = this._normalizeDate(dates[0]);
|
|
139
|
+
const end = this._normalizeDate(dates[1]);
|
|
140
|
+
if (start && end)
|
|
141
|
+
acc[key] = [start, end];
|
|
142
|
+
return acc;
|
|
143
|
+
}, {});
|
|
144
|
+
}
|
|
145
|
+
this.updateRangesArray();
|
|
183
146
|
}
|
|
147
|
+
get currentMonth() { return this._currentMonth; }
|
|
184
148
|
set currentMonth(month) {
|
|
185
149
|
if (this._currentMonth !== month) {
|
|
186
150
|
this._currentMonth = month;
|
|
@@ -188,9 +152,7 @@ class NgxsmkDatepickerComponent {
|
|
|
188
152
|
this.generateCalendar();
|
|
189
153
|
}
|
|
190
154
|
}
|
|
191
|
-
get currentYear() {
|
|
192
|
-
return this._currentYear;
|
|
193
|
-
}
|
|
155
|
+
get currentYear() { return this._currentYear; }
|
|
194
156
|
set currentYear(year) {
|
|
195
157
|
if (this._currentYear !== year) {
|
|
196
158
|
this._currentYear = year;
|
|
@@ -199,10 +161,12 @@ class NgxsmkDatepickerComponent {
|
|
|
199
161
|
}
|
|
200
162
|
}
|
|
201
163
|
ngOnInit() {
|
|
164
|
+
if (this._locale === 'en-US') {
|
|
165
|
+
this._locale = navigator.language;
|
|
166
|
+
}
|
|
202
167
|
this.today.setHours(0, 0, 0, 0);
|
|
203
168
|
this.generateLocaleData();
|
|
204
169
|
this.generateTimeOptions();
|
|
205
|
-
// Set default time to current time if enabled and no initial value
|
|
206
170
|
if (this.showTime && !this.value) {
|
|
207
171
|
const now = new Date();
|
|
208
172
|
this.currentHour = now.getHours();
|
|
@@ -223,10 +187,8 @@ class NgxsmkDatepickerComponent {
|
|
|
223
187
|
this.generateLocaleData();
|
|
224
188
|
this.generateCalendar();
|
|
225
189
|
}
|
|
226
|
-
// Regenerate time options if the interval changes
|
|
227
190
|
if (changes['minuteInterval']) {
|
|
228
191
|
this.generateTimeOptions();
|
|
229
|
-
// Recalculate and round current minute to the new interval
|
|
230
192
|
this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;
|
|
231
193
|
this.onTimeChange();
|
|
232
194
|
}
|
|
@@ -235,28 +197,21 @@ class NgxsmkDatepickerComponent {
|
|
|
235
197
|
this.generateCalendar();
|
|
236
198
|
}
|
|
237
199
|
}
|
|
238
|
-
/** Converts the displayed 12h time (currentDisplayHour + isPm) into the 24h internal time (currentHour). */
|
|
239
200
|
get24Hour(displayHour, isPm) {
|
|
240
201
|
if (isPm) {
|
|
241
|
-
return displayHour === 12 ? 12 : displayHour + 12;
|
|
242
|
-
}
|
|
243
|
-
else {
|
|
244
|
-
return displayHour === 12 ? 0 : displayHour; // 12 AM is 0 (midnight), 1-11 AM is 1-11
|
|
202
|
+
return displayHour === 12 ? 12 : displayHour + 12;
|
|
245
203
|
}
|
|
204
|
+
return displayHour === 12 ? 0 : displayHour;
|
|
246
205
|
}
|
|
247
|
-
/** Updates the display time variables (12h format and AM/PM state) from the 24h internal time. */
|
|
248
206
|
update12HourState(fullHour) {
|
|
249
207
|
this.isPm = fullHour >= 12;
|
|
250
|
-
this.currentDisplayHour = fullHour % 12 || 12;
|
|
208
|
+
this.currentDisplayHour = fullHour % 12 || 12;
|
|
251
209
|
}
|
|
252
|
-
/** Applies the currently selected hour and minute to a given date object. */
|
|
253
210
|
applyCurrentTime(date) {
|
|
254
|
-
// Convert 12h display state back to 24h format
|
|
255
211
|
this.currentHour = this.get24Hour(this.currentDisplayHour, this.isPm);
|
|
256
212
|
date.setHours(this.currentHour, this.currentMinute, 0, 0);
|
|
257
213
|
return date;
|
|
258
214
|
}
|
|
259
|
-
/** Initializes selection state and time controls from the provided input value. */
|
|
260
215
|
initializeValue(value) {
|
|
261
216
|
if (!value) {
|
|
262
217
|
this.selectedDate = null;
|
|
@@ -276,15 +231,12 @@ class NgxsmkDatepickerComponent {
|
|
|
276
231
|
}
|
|
277
232
|
if (initialDate) {
|
|
278
233
|
this.currentDate = new Date(initialDate);
|
|
279
|
-
// Set time selectors based on 24h value from initial date
|
|
280
234
|
this.currentHour = initialDate.getHours();
|
|
281
235
|
this.currentMinute = initialDate.getMinutes();
|
|
282
236
|
this.update12HourState(this.currentHour);
|
|
283
|
-
// Round minute to nearest interval, in case the initial value time doesn't match the current interval
|
|
284
237
|
this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;
|
|
285
238
|
}
|
|
286
239
|
}
|
|
287
|
-
/** Normalizes a date input to a Date object, keeping time information. */
|
|
288
240
|
_normalizeDate(date) {
|
|
289
241
|
if (!date)
|
|
290
242
|
return null;
|
|
@@ -293,12 +245,10 @@ class NgxsmkDatepickerComponent {
|
|
|
293
245
|
return null;
|
|
294
246
|
return d;
|
|
295
247
|
}
|
|
296
|
-
/** Generates options for the hour and minute selectors based on the interval. */
|
|
297
248
|
generateTimeOptions() {
|
|
298
|
-
// Hours are 1 through 12 for 12h format display
|
|
299
249
|
this.hourOptions = Array.from({ length: 12 }).map((_, i) => ({
|
|
300
250
|
label: (i + 1).toString().padStart(2, '0'),
|
|
301
|
-
value: i + 1,
|
|
251
|
+
value: i + 1,
|
|
302
252
|
}));
|
|
303
253
|
this.minuteOptions = [];
|
|
304
254
|
for (let i = 0; i < 60; i += this.minuteInterval) {
|
|
@@ -308,7 +258,6 @@ class NgxsmkDatepickerComponent {
|
|
|
308
258
|
});
|
|
309
259
|
}
|
|
310
260
|
}
|
|
311
|
-
/** Generates locale-dependent month and weekday names. */
|
|
312
261
|
generateLocaleData() {
|
|
313
262
|
this.monthOptions = Array.from({ length: 12 }).map((_, i) => ({
|
|
314
263
|
label: new Date(2024, i, 1).toLocaleDateString(this.locale, { month: 'long' }),
|
|
@@ -327,27 +276,22 @@ class NgxsmkDatepickerComponent {
|
|
|
327
276
|
return weekDay;
|
|
328
277
|
});
|
|
329
278
|
}
|
|
330
|
-
/** Populates the internal array of predefined ranges. */
|
|
331
279
|
updateRangesArray() {
|
|
332
280
|
this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({ key, value })) : [];
|
|
333
281
|
}
|
|
334
|
-
/** Handles selection of a predefined date range. */
|
|
335
282
|
selectRange(range) {
|
|
336
283
|
this.startDate = this.applyCurrentTime(range[0]);
|
|
337
284
|
this.endDate = this.applyCurrentTime(range[1]);
|
|
338
285
|
if (this.startDate && this.endDate) {
|
|
339
|
-
/** Type assertion is safe here as both dates are explicitly set */
|
|
340
286
|
this.valueChange.emit({ start: this.startDate, end: this.endDate });
|
|
341
287
|
}
|
|
342
288
|
this.currentDate = new Date(this.startDate);
|
|
343
|
-
this.initializeValue({ start: this.startDate, end: this.endDate });
|
|
289
|
+
this.initializeValue({ start: this.startDate, end: this.endDate });
|
|
344
290
|
this.generateCalendar();
|
|
345
291
|
}
|
|
346
|
-
/** Checks if a specific date should be disabled based on minDate, maxDate, or custom function. */
|
|
347
292
|
isDateDisabled(date) {
|
|
348
293
|
if (!date)
|
|
349
294
|
return false;
|
|
350
|
-
// Check against minDate/maxDate, ensuring we compare only the date part
|
|
351
295
|
const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
352
296
|
if (this._minDate) {
|
|
353
297
|
const minDateOnly = new Date(this._minDate.getFullYear(), this._minDate.getMonth(), this._minDate.getDate());
|
|
@@ -359,11 +303,8 @@ class NgxsmkDatepickerComponent {
|
|
|
359
303
|
if (dateOnly > maxDateOnly)
|
|
360
304
|
return true;
|
|
361
305
|
}
|
|
362
|
-
|
|
363
|
-
return true;
|
|
364
|
-
return false;
|
|
306
|
+
return this.isInvalidDate(date);
|
|
365
307
|
}
|
|
366
|
-
/** Updates the time component of the selected date(s) when hour/minute selectors change. */
|
|
367
308
|
onTimeChange() {
|
|
368
309
|
if (this.mode === 'single' && this.selectedDate) {
|
|
369
310
|
this.selectedDate = this.applyCurrentTime(this.selectedDate);
|
|
@@ -372,15 +313,12 @@ class NgxsmkDatepickerComponent {
|
|
|
372
313
|
else if (this.mode === 'range' && this.startDate && this.endDate) {
|
|
373
314
|
this.startDate = this.applyCurrentTime(this.startDate);
|
|
374
315
|
this.endDate = this.applyCurrentTime(this.endDate);
|
|
375
|
-
/** Type assertion is safe here as both dates are confirmed */
|
|
376
316
|
this.valueChange.emit({ start: this.startDate, end: this.endDate });
|
|
377
317
|
}
|
|
378
318
|
else if (this.mode === 'range' && this.startDate && !this.endDate) {
|
|
379
|
-
// If range started but not completed, update time on the start date only (no emit)
|
|
380
319
|
this.startDate = this.applyCurrentTime(this.startDate);
|
|
381
320
|
}
|
|
382
321
|
}
|
|
383
|
-
/** Handles the click event on a calendar day cell. */
|
|
384
322
|
onDateClick(day) {
|
|
385
323
|
if (!day || this.isDateDisabled(day))
|
|
386
324
|
return;
|
|
@@ -389,14 +327,12 @@ class NgxsmkDatepickerComponent {
|
|
|
389
327
|
this.valueChange.emit(this.selectedDate);
|
|
390
328
|
}
|
|
391
329
|
else {
|
|
392
|
-
// Range selection logic
|
|
393
330
|
if (!this.startDate || (this.startDate && this.endDate)) {
|
|
394
331
|
this.startDate = this.applyCurrentTime(day);
|
|
395
332
|
this.endDate = null;
|
|
396
333
|
}
|
|
397
334
|
else if (day >= this.startDate) {
|
|
398
335
|
this.endDate = this.applyCurrentTime(day);
|
|
399
|
-
/** Type assertion is safe here as both dates are set when ending a range */
|
|
400
336
|
this.valueChange.emit({ start: this.startDate, end: this.endDate });
|
|
401
337
|
}
|
|
402
338
|
else {
|
|
@@ -405,7 +341,6 @@ class NgxsmkDatepickerComponent {
|
|
|
405
341
|
}
|
|
406
342
|
this.hoveredDate = null;
|
|
407
343
|
}
|
|
408
|
-
// Update time controls to reflect the time of the newly selected date
|
|
409
344
|
if (this.mode === 'single' && this.selectedDate) {
|
|
410
345
|
this.update12HourState(this.selectedDate.getHours());
|
|
411
346
|
this.currentMinute = this.selectedDate.getMinutes();
|
|
@@ -415,13 +350,11 @@ class NgxsmkDatepickerComponent {
|
|
|
415
350
|
this.currentMinute = this.startDate.getMinutes();
|
|
416
351
|
}
|
|
417
352
|
}
|
|
418
|
-
/** Handles hover events for range preview when only the start date is selected. */
|
|
419
353
|
onDateHover(day) {
|
|
420
354
|
if (this.mode === 'range' && this.startDate && !this.endDate && day) {
|
|
421
355
|
this.hoveredDate = day;
|
|
422
356
|
}
|
|
423
357
|
}
|
|
424
|
-
/** Checks if a date is within the range being previewed (during hover). */
|
|
425
358
|
isPreviewInRange(day) {
|
|
426
359
|
if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day)
|
|
427
360
|
return false;
|
|
@@ -430,7 +363,6 @@ class NgxsmkDatepickerComponent {
|
|
|
430
363
|
const time = day.getTime();
|
|
431
364
|
return time > Math.min(start, end) && time < Math.max(start, end);
|
|
432
365
|
}
|
|
433
|
-
/** Generates the calendar grid for the currently active month. */
|
|
434
366
|
generateCalendar() {
|
|
435
367
|
this.daysInMonth = [];
|
|
436
368
|
const year = this.currentDate.getFullYear();
|
|
@@ -449,7 +381,6 @@ class NgxsmkDatepickerComponent {
|
|
|
449
381
|
this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));
|
|
450
382
|
}
|
|
451
383
|
}
|
|
452
|
-
/** Generates month and year options for dropdowns. */
|
|
453
384
|
generateDropdownOptions() {
|
|
454
385
|
const startYear = this._currentYear - 10;
|
|
455
386
|
const endYear = this._currentYear + 10;
|
|
@@ -458,12 +389,10 @@ class NgxsmkDatepickerComponent {
|
|
|
458
389
|
this.yearOptions.push({ label: `${i}`, value: i });
|
|
459
390
|
}
|
|
460
391
|
}
|
|
461
|
-
/** Moves the calendar view forward or backward by one month. */
|
|
462
392
|
changeMonth(delta) {
|
|
463
393
|
this.currentDate.setMonth(this.currentDate.getMonth() + delta);
|
|
464
394
|
this.generateCalendar();
|
|
465
395
|
}
|
|
466
|
-
/** Utility function to check if two dates represent the same day (ignoring time). */
|
|
467
396
|
isSameDay(d1, d2) {
|
|
468
397
|
if (!d1 || !d2)
|
|
469
398
|
return false;
|
|
@@ -471,11 +400,9 @@ class NgxsmkDatepickerComponent {
|
|
|
471
400
|
d1.getMonth() === d2.getMonth() &&
|
|
472
401
|
d1.getDate() === d2.getDate());
|
|
473
402
|
}
|
|
474
|
-
/** Checks if a date is strictly between the start and end of a selected range (ignoring time). */
|
|
475
403
|
isInRange(d) {
|
|
476
404
|
if (!d || !this.startDate || !this.endDate)
|
|
477
405
|
return false;
|
|
478
|
-
// Use date-only comparison for highlighting the days
|
|
479
406
|
const dTime = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();
|
|
480
407
|
const startDayTime = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate()).getTime();
|
|
481
408
|
const endDayTime = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate()).getTime();
|
|
@@ -483,7 +410,7 @@ class NgxsmkDatepickerComponent {
|
|
|
483
410
|
const endTime = Math.max(startDayTime, endDayTime);
|
|
484
411
|
return dTime > startTime && dTime < endTime;
|
|
485
412
|
}
|
|
486
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, deps: [
|
|
413
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
487
414
|
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", 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: `
|
|
488
415
|
<div class="ngxsmk-datepicker-container">
|
|
489
416
|
@if (showRanges && rangesArray.length > 0 && mode === 'range') {
|
|
@@ -653,10 +580,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImpor
|
|
|
653
580
|
</div>
|
|
654
581
|
</div>
|
|
655
582
|
`, 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"] }]
|
|
656
|
-
}],
|
|
657
|
-
type: Inject,
|
|
658
|
-
args: [PLATFORM_ID]
|
|
659
|
-
}] }], propDecorators: { mode: [{
|
|
583
|
+
}], propDecorators: { mode: [{
|
|
660
584
|
type: Input
|
|
661
585
|
}], isInvalidDate: [{
|
|
662
586
|
type: Input
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ngxsmk-datepicker.mjs","sources":["../../../projects/ngxsmk-datepicker/src/lib/ngxsmk-datepicker.ts","../../../projects/ngxsmk-datepicker/src/public-api.ts","../../../projects/ngxsmk-datepicker/src/ngxsmk-datepicker.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n HostBinding,\r\n HostListener,\r\n Inject,\r\n Input,\r\n OnChanges,\r\n OnInit,\r\n Output,\r\n PLATFORM_ID,\r\n SimpleChanges,\r\n} from '@angular/core';\r\nimport {CommonModule, isPlatformBrowser} from '@angular/common';\r\nimport {FormsModule} from '@angular/forms';\r\n\r\n// #####################################################################\r\n// ## Reusable Custom Select Component\r\n// #####################################################################\r\n@Component({\r\n selector: 'app-custom-select',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"ngxsmk-select-container\" (click)=\"toggleDropdown()\">\r\n <button type=\"button\" class=\"ngxsmk-select-display\">\r\n <span>{{ displayValue }}</span>\r\n <svg class=\"ngxsmk-arrow-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M112 184l144 144 144-144\"/>\r\n </svg>\r\n </button>\r\n @if (isOpen) {\r\n <div class=\"ngxsmk-options-panel\">\r\n <ul>\r\n @for (option of options; track option.value) {\r\n <li [class.selected]=\"option.value === value\" (click)=\"selectOption(option); $event.stopPropagation()\">\r\n {{ option.label }}\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n\r\n .ngxsmk-select-container {\r\n cursor: pointer;\r\n }\r\n\r\n .ngxsmk-select-display {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: var(--custom-select-width, 115px);\r\n background: var(--datepicker-background, #fff);\r\n border: 1px solid var(--datepicker-border-color, #ccc);\r\n color: var(--datepicker-text-color, #333);\r\n border-radius: 4px;\r\n padding: 4px 8px;\r\n font-size: 14px;\r\n text-align: left;\r\n height: 30px;\r\n }\r\n\r\n .ngxsmk-arrow-icon {\r\n width: 12px;\r\n height: 12px;\r\n margin-left: 8px;\r\n }\r\n\r\n .ngxsmk-options-panel {\r\n position: absolute;\r\n top: 110%; /* Relative to the host element's height */\r\n left: 0;\r\n width: 100%;\r\n background: var(--datepicker-background, #fff);\r\n border: 1px solid var(--datepicker-border-color, #ccc);\r\n color: var(--datepicker-text-color, #333);\r\n border-radius: 4px;\r\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\r\n max-height: 200px;\r\n overflow-y: auto;\r\n z-index: 9999; /* Highest Z-index for visibility */\r\n }\r\n\r\n .ngxsmk-options-panel ul {\r\n list-style: none;\r\n padding: 4px;\r\n margin: 0;\r\n }\r\n\r\n .ngxsmk-options-panel li {\r\n padding: 8px 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n }\r\n\r\n .ngxsmk-options-panel li:hover {\r\n background-color: var(--datepicker-hover-background, #f0f0f0);\r\n }\r\n\r\n .ngxsmk-options-panel li.selected {\r\n background-color: var(--datepicker-primary-color, #3880ff);\r\n color: var(--datepicker-primary-contrast, #fff);\r\n }\r\n `],\r\n})\r\nexport class CustomSelectComponent {\r\n /** The list of available options to display in the dropdown. */\r\n @Input() options: { label: string; value: any }[] = [];\r\n /** The currently selected value. */\r\n @Input() value: any;\r\n /** Emits the new value when an option is selected. */\r\n @Output() valueChange = new EventEmitter<any>();\r\n public isOpen = false;\r\n\r\n constructor(private readonly elementRef: ElementRef) {\r\n }\r\n\r\n /** Closes the dropdown when a click occurs outside the component boundary. */\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: MouseEvent): void {\r\n if (!this.elementRef.nativeElement.contains(event.target)) this.isOpen = false;\r\n }\r\n\r\n /** Gets the display label for the currently selected value. */\r\n get displayValue(): string {\r\n const selectedOption = this.options.find((opt) => opt.value === this.value);\r\n return selectedOption ? selectedOption.label : '';\r\n }\r\n\r\n /** Toggles the visibility of the dropdown panel. */\r\n toggleDropdown(): void {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n /** Handles the selection of a new option. */\r\n selectOption(option: { label: string; value: any }): void {\r\n this.value = option.value;\r\n this.valueChange.emit(this.value);\r\n this.isOpen = false;\r\n }\r\n}\r\n\r\n// #####################################################################\r\n// ## Datepicker Component\r\n// #####################################################################\r\nexport type DateInput = Date | string | { toDate: () => Date; _isAMomentObject?: boolean; $d?: Date };\r\n\r\nexport interface DateRange {\r\n [key: string]: [DateInput, DateInput];\r\n}\r\n\r\n@Component({\r\n selector: 'ngxsmk-datepicker',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, CustomSelectComponent],\r\n template: `\r\n <div class=\"ngxsmk-datepicker-container\">\r\n @if (showRanges && rangesArray.length > 0 && mode === 'range') {\r\n <div class=\"ngxsmk-ranges-container\">\r\n <ul>\r\n @for (range of rangesArray; track range.key) {\r\n <li (click)=\"selectRange(range.value)\">{{ range.key }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n <div class=\"ngxsmk-calendar-container\">\r\n <div class=\"ngxsmk-header\">\r\n <div class=\"ngxsmk-month-year-selects\">\r\n <app-custom-select class=\"month-select\" [options]=\"monthOptions\"\r\n [(value)]=\"currentMonth\"></app-custom-select>\r\n <app-custom-select class=\"year-select\" [options]=\"yearOptions\" [(value)]=\"currentYear\"></app-custom-select>\r\n </div>\r\n <div class=\"ngxsmk-nav-buttons\">\r\n <button type=\"button\" class=\"ngxsmk-nav-button\" (click)=\"changeMonth(-1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M328 112L184 256l144 144\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"ngxsmk-nav-button\" (click)=\"changeMonth(1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M184 112l144 144-144 144\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"ngxsmk-days-grid-wrapper\">\r\n <div class=\"ngxsmk-days-grid\">\r\n @for (day of weekDays; track day) {\r\n <div class=\"ngxsmk-day-name\">{{ day }}</div>\r\n }\r\n @for (day of daysInMonth; track $index) {\r\n <div class=\"ngxsmk-day-cell\"\r\n [class.empty]=\"!day\" [class.disabled]=\"isDateDisabled(day)\" [class.today]=\"isSameDay(day, today)\"\r\n [class.selected]=\"mode === 'single' && isSameDay(day, selectedDate)\"\r\n [class.start-date]=\"mode === 'range' && isSameDay(day, startDate)\"\r\n [class.end-date]=\"mode === 'range' && isSameDay(day, endDate)\"\r\n [class.in-range]=\"mode === 'range' && isInRange(day)\"\r\n [class.preview-range]=\"isPreviewInRange(day)\"\r\n (click)=\"onDateClick(day)\" (mouseenter)=\"onDateHover(day)\">\r\n @if (day) {\r\n <div class=\"ngxsmk-day-number\">{{ day | date : 'd' }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showTime) {\r\n <div class=\"ngxsmk-time-selection\">\r\n <span class=\"ngxsmk-time-label\">Time:</span>\r\n <app-custom-select\r\n class=\"hour-select\"\r\n [options]=\"hourOptions\"\r\n [(value)]=\"currentDisplayHour\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n <span class=\"ngxsmk-time-separator\">:</span>\r\n <app-custom-select\r\n class=\"minute-select\"\r\n [options]=\"minuteOptions\"\r\n [(value)]=\"currentMinute\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n <app-custom-select\r\n class=\"ampm-select\"\r\n [options]=\"ampmOptions\"\r\n [(value)]=\"isPm\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --datepicker-primary-color: #6d28d9;\r\n --datepicker-primary-contrast: #ffffff;\r\n --datepicker-range-background: #f5f3ff;\r\n --datepicker-background: #ffffff;\r\n --datepicker-text-color: #222428;\r\n --datepicker-subtle-text-color: #9ca3af;\r\n --datepicker-border-color: #e9e9e9;\r\n --datepicker-hover-background: #f0f0f0;\r\n }\r\n\r\n :host(.dark-theme) {\r\n --datepicker-range-background: rgba(139, 92, 246, 0.2);\r\n --datepicker-background: #1f2937;\r\n --datepicker-text-color: #d1d5db;\r\n --datepicker-subtle-text-color: #6b7280;\r\n --datepicker-border-color: #4b5563;\r\n --datepicker-hover-background: #374151;\r\n }\r\n\r\n .ngxsmk-datepicker-container {\r\n display: flex;\r\n }\r\n\r\n .ngxsmk-calendar-container {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n border-radius: 10px;\r\n padding: 16px;\r\n background: var(--datepicker-background);\r\n }\r\n\r\n .ngxsmk-header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 12px;\r\n position: relative;\r\n z-index: 2;\r\n gap: 5px;\r\n }\r\n\r\n .ngxsmk-month-year-selects {\r\n display: flex;\r\n gap: 5px;\r\n }\r\n\r\n .ngxsmk-month-year-selects app-custom-select.month-select {\r\n --custom-select-width: 120px;\r\n }\r\n\r\n .ngxsmk-month-year-selects app-custom-select.year-select {\r\n --custom-select-width: 90px;\r\n }\r\n\r\n .ngxsmk-nav-buttons {\r\n display: flex;\r\n }\r\n\r\n .ngxsmk-nav-button {\r\n background: none;\r\n border: none;\r\n padding: 8px;\r\n cursor: pointer;\r\n border-radius: 50%;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--datepicker-text-color);\r\n }\r\n\r\n .ngxsmk-nav-button:hover {\r\n background-color: var(--datepicker-hover-background);\r\n }\r\n\r\n .ngxsmk-nav-button svg {\r\n width: 18px;\r\n height: 18px;\r\n }\r\n\r\n .ngxsmk-days-grid-wrapper {\r\n position: relative;\r\n }\r\n\r\n .ngxsmk-days-grid {\r\n display: grid;\r\n grid-template-columns: repeat(7, 1fr);\r\n text-align: center;\r\n gap: 0;\r\n }\r\n\r\n .ngxsmk-day-name {\r\n font-weight: 600;\r\n font-size: 0.8rem;\r\n color: var(--datepicker-subtle-text-color);\r\n padding: 8px 0;\r\n }\r\n\r\n .ngxsmk-day-cell {\r\n position: relative;\r\n height: 38px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n cursor: pointer;\r\n border-radius: 0;\r\n }\r\n\r\n .ngxsmk-day-number {\r\n width: 36px;\r\n height: 36px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n border-radius: 50%;\r\n color: var(--datepicker-text-color);\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number {\r\n background-color: var(--datepicker-hover-background);\r\n color: var(--datepicker-primary-color);\r\n }\r\n\r\n .ngxsmk-day-cell.start-date .ngxsmk-day-number,\r\n .ngxsmk-day-cell.end-date .ngxsmk-day-number,\r\n .ngxsmk-day-cell.selected .ngxsmk-day-number {\r\n background-color: var(--datepicker-primary-color);\r\n color: var(--datepicker-primary-contrast);\r\n }\r\n\r\n /* --- Range Highlight --- */\r\n .ngxsmk-day-cell.in-range,\r\n .ngxsmk-day-cell.start-date,\r\n .ngxsmk-day-cell.end-date,\r\n .ngxsmk-day-cell.preview-range {\r\n background-color: var(--datepicker-range-background);\r\n }\r\n\r\n /* Apply radius to the edge cells */\r\n .ngxsmk-day-cell.start-date {\r\n border-top-left-radius: 100%;\r\n border-bottom-left-radius: 100%;\r\n }\r\n\r\n .ngxsmk-day-cell.end-date {\r\n border-top-right-radius: 100%;\r\n border-bottom-right-radius: 100%;\r\n }\r\n\r\n .ngxsmk-day-cell.start-date.end-date {\r\n border-radius: 50px;\r\n }\r\n /* --- End Range Highlight --- */\r\n\r\n .ngxsmk-day-cell.disabled {\r\n background-color: transparent !important;\r\n color: #4b5563;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n opacity: 0.5;\r\n }\r\n\r\n .ngxsmk-day-cell.today .ngxsmk-day-number {\r\n border: 1px solid var(--datepicker-primary-color);\r\n }\r\n\r\n .ngxsmk-ranges-container {\r\n width: 180px;\r\n padding: 16px;\r\n border-right: 1px solid var(--datepicker-border-color);\r\n background: var(--datepicker-background);\r\n }\r\n\r\n .ngxsmk-ranges-container ul {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n\r\n .ngxsmk-ranges-container li {\r\n padding: 10px;\r\n margin-bottom: 8px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n color: var(--datepicker-text-color);\r\n }\r\n\r\n .ngxsmk-ranges-container li:hover {\r\n background-color: var(--datepicker-hover-background);\r\n }\r\n\r\n .ngxsmk-time-selection {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 4px;\r\n margin-top: 16px;\r\n padding-top: 12px;\r\n border-top: 1px solid var(--datepicker-border-color);\r\n }\r\n\r\n .ngxsmk-time-label {\r\n font-size: 0.9rem;\r\n color: var(--datepicker-subtle-text-color);\r\n margin-right: 4px;\r\n }\r\n\r\n .ngxsmk-time-selection app-custom-select {\r\n --custom-select-width: 60px;\r\n height: 30px;\r\n }\r\n\r\n .ngxsmk-time-selection app-custom-select.ampm-select {\r\n --custom-select-width: 70px;\r\n }\r\n\r\n .ngxsmk-time-separator {\r\n font-weight: 600;\r\n font-size: 1.1rem;\r\n color: var(--datepicker-text-color);\r\n }\r\n `],\r\n})\r\nexport class NgxsmkDatepickerComponent implements OnInit, OnChanges {\r\n /** Sets the selection mode: 'single' date or 'range' selection. */\r\n @Input() mode: 'single' | 'range' = 'single';\r\n /** A function to programmatically disable specific dates. Returns true if the date should be disabled. */\r\n @Input() isInvalidDate: (date: Date) => boolean = () => false;\r\n /** If true, displays the predefined ranges panel when in 'range' mode. */\r\n @Input() showRanges: boolean = true;\r\n /** If true, displays the time selection controls (hour/minute). */\r\n @Input() showTime: boolean = false;\r\n /** Sets the minute selection step/interval (e.g., 5, 15, 30). */\r\n @Input() minuteInterval: number = 1;\r\n\r\n /** The initial selected date or date range. Accepts Date, or { start: Date, end: Date }. */\r\n @Input() value: Date | { start: Date, end: Date } | null = null;\r\n\r\n private _locale: string = 'en-US';\r\n\r\n /** Sets the locale for language and regional formatting (e.g., 'en-US', 'de-DE'). */\r\n @Input() set locale(value: string) {\r\n this._locale = value;\r\n }\r\n\r\n get locale(): string {\r\n return this._locale;\r\n }\r\n\r\n /** Controls the visual theme: 'light' or 'dark'. */\r\n @Input() theme: 'light' | 'dark' = 'light';\r\n\r\n @HostBinding('class.dark-theme') get isDarkMode() {\r\n return this.theme === 'dark';\r\n }\r\n\r\n /** Emits the newly selected date or date range. */\r\n @Output() valueChange = new EventEmitter<Date | { start: Date; end: Date }>();\r\n\r\n private _minDate: Date | null = null;\r\n\r\n /** The earliest selectable date. */\r\n @Input() set minDate(value: DateInput | null) {\r\n this._minDate = this._normalizeDate(value);\r\n }\r\n\r\n private _maxDate: Date | null = null;\r\n\r\n /** The latest selectable date. */\r\n @Input() set maxDate(value: DateInput | null) {\r\n this._maxDate = this._normalizeDate(value);\r\n }\r\n\r\n private _ranges: { [key: string]: [Date, Date] } | null = null;\r\n\r\n /** An object of predefined date ranges for quick selection. */\r\n @Input() set ranges(value: DateRange | null) {\r\n if (!value) {\r\n this._ranges = null;\r\n } else {\r\n this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {\r\n const start = this._normalizeDate(dates[0]);\r\n const end = this._normalizeDate(dates[1]);\r\n if (start && end) acc[key] = [start, end];\r\n return acc;\r\n }, {} as { [key: string]: [Date, Date] });\r\n }\r\n this.updateRangesArray();\r\n }\r\n\r\n public currentDate: Date = new Date();\r\n public daysInMonth: (Date | null)[] = [];\r\n public weekDays: string[] = [];\r\n public readonly today: Date = new Date();\r\n public selectedDate: Date | null = null;\r\n public startDate: Date | null = null;\r\n public endDate: Date | null = null;\r\n public hoveredDate: Date | null = null;\r\n public rangesArray: { key: string; value: [Date, Date] }[] = [];\r\n private _currentMonth!: number;\r\n private _currentYear!: number;\r\n public monthOptions: { label: string; value: number }[] = [];\r\n public yearOptions: { label: string; value: number }[] = [];\r\n private firstDayOfWeek: number = 0;\r\n\r\n // Time selection state\r\n public currentHour: number = 0; // Internal 24h format (0-23)\r\n public currentMinute: number = 0;\r\n public currentDisplayHour: number = 12; // Display 12h format (1-12)\r\n public isPm: boolean = false; // Tracks AM/PM status\r\n\r\n public hourOptions: { label: string; value: number }[] = [];\r\n public minuteOptions: { label: string; value: number }[] = [];\r\n public ampmOptions: { label: string; value: boolean }[] = [\r\n { label: 'AM', value: false },\r\n { label: 'PM', value: true }\r\n ];\r\n\r\n\r\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {\r\n if (isPlatformBrowser(this.platformId)) {\r\n this._locale = navigator.language;\r\n }\r\n }\r\n\r\n get currentMonth(): number {\r\n return this._currentMonth;\r\n }\r\n\r\n set currentMonth(month: number) {\r\n if (this._currentMonth !== month) {\r\n this._currentMonth = month;\r\n this.currentDate.setMonth(month);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n get currentYear(): number {\r\n return this._currentYear;\r\n }\r\n\r\n set currentYear(year: number) {\r\n if (this._currentYear !== year) {\r\n this._currentYear = year;\r\n this.currentDate.setFullYear(year);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n this.today.setHours(0, 0, 0, 0);\r\n this.generateLocaleData();\r\n this.generateTimeOptions();\r\n\r\n // Set default time to current time if enabled and no initial value\r\n if (this.showTime && !this.value) {\r\n const now = new Date();\r\n\r\n this.currentHour = now.getHours();\r\n this.currentMinute = Math.floor(now.getMinutes() / this.minuteInterval) * this.minuteInterval;\r\n\r\n if (this.currentMinute === 60) {\r\n this.currentMinute = 0;\r\n this.currentHour = (this.currentHour + 1) % 24;\r\n }\r\n\r\n this.update12HourState(this.currentHour);\r\n }\r\n\r\n if (this.value) {\r\n this.initializeValue(this.value);\r\n }\r\n this.generateCalendar();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['locale']) {\r\n this.generateLocaleData();\r\n this.generateCalendar();\r\n }\r\n\r\n // Regenerate time options if the interval changes\r\n if (changes['minuteInterval']) {\r\n this.generateTimeOptions();\r\n // Recalculate and round current minute to the new interval\r\n this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;\r\n this.onTimeChange();\r\n }\r\n\r\n if (changes['value'] && changes['value'].currentValue !== changes['value'].previousValue) {\r\n this.initializeValue(changes['value'].currentValue);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n /** Converts the displayed 12h time (currentDisplayHour + isPm) into the 24h internal time (currentHour). */\r\n private get24Hour(displayHour: number, isPm: boolean): number {\r\n if (isPm) {\r\n return displayHour === 12 ? 12 : displayHour + 12; // 12 PM is 12, 1-11 PM is 13-23\r\n } else {\r\n return displayHour === 12 ? 0 : displayHour; // 12 AM is 0 (midnight), 1-11 AM is 1-11\r\n }\r\n }\r\n\r\n /** Updates the display time variables (12h format and AM/PM state) from the 24h internal time. */\r\n private update12HourState(fullHour: number): void {\r\n this.isPm = fullHour >= 12;\r\n this.currentDisplayHour = fullHour % 12 || 12; // 0 (midnight) or 12 PM both become 12\r\n }\r\n\r\n /** Applies the currently selected hour and minute to a given date object. */\r\n private applyCurrentTime(date: Date): Date {\r\n // Convert 12h display state back to 24h format\r\n this.currentHour = this.get24Hour(this.currentDisplayHour, this.isPm);\r\n date.setHours(this.currentHour, this.currentMinute, 0, 0);\r\n return date;\r\n }\r\n\r\n /** Initializes selection state and time controls from the provided input value. */\r\n private initializeValue(value: Date | { start: Date, end: Date } | null): void {\r\n if (!value) {\r\n this.selectedDate = null;\r\n this.startDate = null;\r\n this.endDate = null;\r\n return;\r\n }\r\n\r\n let initialDate: Date | null = null;\r\n\r\n if (this.mode === 'single' && value instanceof Date) {\r\n this.selectedDate = this._normalizeDate(value);\r\n initialDate = this.selectedDate;\r\n\r\n } else if (this.mode === 'range' && typeof value === 'object' && 'start' in value && 'end' in value) {\r\n this.startDate = this._normalizeDate(value.start);\r\n this.endDate = this._normalizeDate(value.end);\r\n initialDate = this.startDate;\r\n }\r\n\r\n if (initialDate) {\r\n this.currentDate = new Date(initialDate);\r\n\r\n // Set time selectors based on 24h value from initial date\r\n this.currentHour = initialDate.getHours();\r\n this.currentMinute = initialDate.getMinutes();\r\n\r\n this.update12HourState(this.currentHour);\r\n\r\n // Round minute to nearest interval, in case the initial value time doesn't match the current interval\r\n this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;\r\n }\r\n }\r\n\r\n /** Normalizes a date input to a Date object, keeping time information. */\r\n private _normalizeDate(date: DateInput | null): Date | null {\r\n if (!date) return null;\r\n const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date as any);\r\n if (isNaN(d.getTime())) return null;\r\n return d;\r\n }\r\n\r\n /** Generates options for the hour and minute selectors based on the interval. */\r\n private generateTimeOptions(): void {\r\n // Hours are 1 through 12 for 12h format display\r\n this.hourOptions = Array.from({ length: 12 }).map((_, i) => ({\r\n label: (i + 1).toString().padStart(2, '0'),\r\n value: i + 1, // Values 1 through 12\r\n }));\r\n\r\n this.minuteOptions = [];\r\n for (let i = 0; i < 60; i += this.minuteInterval) {\r\n this.minuteOptions.push({\r\n label: i.toString().padStart(2, '0'),\r\n value: i,\r\n });\r\n }\r\n }\r\n\r\n /** Generates locale-dependent month and weekday names. */\r\n private generateLocaleData(): void {\r\n this.monthOptions = Array.from({length: 12}).map((_, i) => ({\r\n label: new Date(2024, i, 1).toLocaleDateString(this.locale, {month: 'long'}),\r\n value: i,\r\n }));\r\n try {\r\n this.firstDayOfWeek = ((new Intl.Locale(this.locale) as any).weekInfo?.firstDay || 0) % 7;\r\n } catch (e) {\r\n this.firstDayOfWeek = 0;\r\n }\r\n const day = new Date(2024, 0, 7 + this.firstDayOfWeek);\r\n this.weekDays = Array.from({length: 7}).map(() => {\r\n const weekDay = new Date(day).toLocaleDateString(this.locale, {weekday: 'short'});\r\n day.setDate(day.getDate() + 1);\r\n return weekDay;\r\n });\r\n }\r\n\r\n /** Populates the internal array of predefined ranges. */\r\n private updateRangesArray(): void {\r\n this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({key, value})) : [];\r\n }\r\n\r\n /** Handles selection of a predefined date range. */\r\n public selectRange(range: [Date, Date]): void {\r\n this.startDate = this.applyCurrentTime(range[0]);\r\n this.endDate = this.applyCurrentTime(range[1]);\r\n\r\n if (this.startDate && this.endDate) {\r\n /** Type assertion is safe here as both dates are explicitly set */\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n }\r\n\r\n this.currentDate = new Date(this.startDate);\r\n this.initializeValue({start: this.startDate, end: this.endDate}); // Update time selectors\r\n this.generateCalendar();\r\n }\r\n\r\n /** Checks if a specific date should be disabled based on minDate, maxDate, or custom function. */\r\n public isDateDisabled(date: Date | null): boolean {\r\n if (!date) return false;\r\n // Check against minDate/maxDate, ensuring we compare only the date part\r\n const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n\r\n if (this._minDate) {\r\n const minDateOnly = new Date(this._minDate.getFullYear(), this._minDate.getMonth(), this._minDate.getDate());\r\n if (dateOnly < minDateOnly) return true;\r\n }\r\n if (this._maxDate) {\r\n const maxDateOnly = new Date(this._maxDate.getFullYear(), this._maxDate.getMonth(), this._maxDate.getDate());\r\n if (dateOnly > maxDateOnly) return true;\r\n }\r\n\r\n if (this.isInvalidDate(date)) return true;\r\n return false;\r\n }\r\n\r\n /** Updates the time component of the selected date(s) when hour/minute selectors change. */\r\n public onTimeChange(): void {\r\n if (this.mode === 'single' && this.selectedDate) {\r\n this.selectedDate = this.applyCurrentTime(this.selectedDate);\r\n this.valueChange.emit(this.selectedDate);\r\n\r\n } else if (this.mode === 'range' && this.startDate && this.endDate) {\r\n\r\n this.startDate = this.applyCurrentTime(this.startDate);\r\n this.endDate = this.applyCurrentTime(this.endDate);\r\n\r\n /** Type assertion is safe here as both dates are confirmed */\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n\r\n } else if (this.mode === 'range' && this.startDate && !this.endDate) {\r\n // If range started but not completed, update time on the start date only (no emit)\r\n this.startDate = this.applyCurrentTime(this.startDate);\r\n }\r\n }\r\n\r\n /** Handles the click event on a calendar day cell. */\r\n public onDateClick(day: Date | null): void {\r\n if (!day || this.isDateDisabled(day)) return;\r\n\r\n if (this.mode === 'single') {\r\n this.selectedDate = this.applyCurrentTime(day);\r\n this.valueChange.emit(this.selectedDate);\r\n\r\n } else {\r\n // Range selection logic\r\n if (!this.startDate || (this.startDate && this.endDate)) {\r\n this.startDate = this.applyCurrentTime(day);\r\n this.endDate = null;\r\n } else if (day >= this.startDate) {\r\n this.endDate = this.applyCurrentTime(day);\r\n /** Type assertion is safe here as both dates are set when ending a range */\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n } else {\r\n this.startDate = this.applyCurrentTime(day);\r\n this.endDate = null;\r\n }\r\n this.hoveredDate = null;\r\n }\r\n\r\n // Update time controls to reflect the time of the newly selected date\r\n if (this.mode === 'single' && this.selectedDate) {\r\n this.update12HourState(this.selectedDate.getHours());\r\n this.currentMinute = this.selectedDate.getMinutes();\r\n } else if (this.mode === 'range' && this.startDate) {\r\n this.update12HourState(this.startDate.getHours());\r\n this.currentMinute = this.startDate.getMinutes();\r\n }\r\n }\r\n\r\n /** Handles hover events for range preview when only the start date is selected. */\r\n public onDateHover(day: Date | null): void {\r\n if (this.mode === 'range' && this.startDate && !this.endDate && day) {\r\n this.hoveredDate = day;\r\n }\r\n }\r\n\r\n /** Checks if a date is within the range being previewed (during hover). */\r\n public isPreviewInRange(day: Date | null): boolean {\r\n if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day) return false;\r\n const start = this.startDate.getTime();\r\n const end = this.hoveredDate.getTime();\r\n const time = day.getTime();\r\n return time > Math.min(start, end) && time < Math.max(start, end);\r\n }\r\n\r\n /** Generates the calendar grid for the currently active month. */\r\n public generateCalendar(): void {\r\n this.daysInMonth = [];\r\n const year = this.currentDate.getFullYear();\r\n const month = this.currentDate.getMonth();\r\n this._currentMonth = month;\r\n this._currentYear = year;\r\n this.generateDropdownOptions();\r\n const firstDayOfMonth = new Date(year, month, 1);\r\n const lastDayOfMonth = new Date(year, month + 1, 0);\r\n const startDayOfWeek = firstDayOfMonth.getDay();\r\n const emptyCellCount = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;\r\n\r\n for (let i = 0; i < emptyCellCount; i++) {\r\n this.daysInMonth.push(null);\r\n }\r\n for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {\r\n this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));\r\n }\r\n }\r\n\r\n /** Generates month and year options for dropdowns. */\r\n private generateDropdownOptions(): void {\r\n const startYear = this._currentYear - 10;\r\n const endYear = this._currentYear + 10;\r\n this.yearOptions = [];\r\n for (let i = startYear; i <= endYear; i++) {\r\n this.yearOptions.push({label: `${i}`, value: i});\r\n }\r\n }\r\n\r\n /** Moves the calendar view forward or backward by one month. */\r\n public changeMonth(delta: number): void {\r\n this.currentDate.setMonth(this.currentDate.getMonth() + delta);\r\n this.generateCalendar();\r\n }\r\n\r\n /** Utility function to check if two dates represent the same day (ignoring time). */\r\n public isSameDay(d1: Date | null, d2: Date | null): boolean {\r\n if (!d1 || !d2) return false;\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n }\r\n\r\n /** Checks if a date is strictly between the start and end of a selected range (ignoring time). */\r\n public isInRange(d: Date | null): boolean {\r\n if (!d || !this.startDate || !this.endDate) return false;\r\n\r\n // Use date-only comparison for highlighting the days\r\n const dTime = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\r\n const startDayTime = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate()).getTime();\r\n const endDayTime = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate()).getTime();\r\n\r\n const startTime = Math.min(startDayTime, endDayTime);\r\n const endTime = Math.max(startDayTime, endDayTime);\r\n\r\n return dTime > startTime && dTime < endTime;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngxsmk-datepicker\r\n */\r\n\r\nexport * from './lib/ngxsmk-datepicker';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ngxsmk-datepicker.mjs","sources":["../../../projects/ngxsmk-datepicker/src/lib/ngxsmk-datepicker.ts","../../../projects/ngxsmk-datepicker/src/public-api.ts","../../../projects/ngxsmk-datepicker/src/ngxsmk-datepicker.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n HostBinding,\r\n HostListener,\r\n inject,\r\n Input,\r\n OnChanges,\r\n OnInit,\r\n Output,\r\n SimpleChanges,\r\n} from '@angular/core';\r\nimport {CommonModule} from '@angular/common';\r\nimport {FormsModule} from '@angular/forms';\r\n\r\n@Component({\r\n selector: 'app-custom-select',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"ngxsmk-select-container\" (click)=\"toggleDropdown()\">\r\n <button type=\"button\" class=\"ngxsmk-select-display\">\r\n <span>{{ displayValue }}</span>\r\n <svg class=\"ngxsmk-arrow-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M112 184l144 144 144-144\"/>\r\n </svg>\r\n </button>\r\n @if (isOpen) {\r\n <div class=\"ngxsmk-options-panel\">\r\n <ul>\r\n @for (option of options; track option.value) {\r\n <li [class.selected]=\"option.value === value\" (click)=\"selectOption(option); $event.stopPropagation()\">\r\n {{ option.label }}\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host { position: relative; display: inline-block; }\r\n .ngxsmk-select-container { cursor: pointer; }\r\n .ngxsmk-select-display {\r\n display: flex; align-items: center; justify-content: space-between;\r\n width: var(--custom-select-width, 115px); background: var(--datepicker-background, #fff);\r\n border: 1px solid var(--datepicker-border-color, #ccc); color: var(--datepicker-text-color, #333);\r\n border-radius: 4px; padding: 4px 8px; font-size: 14px; text-align: left; height: 30px;\r\n }\r\n .ngxsmk-arrow-icon { width: 12px; height: 12px; margin-left: 8px; }\r\n .ngxsmk-options-panel {\r\n position: absolute; top: 110%; left: 0; width: 100%;\r\n background: var(--datepicker-background, #fff); border: 1px solid var(--datepicker-border-color, #ccc);\r\n color: var(--datepicker-text-color, #333); border-radius: 4px;\r\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); max-height: 200px; overflow-y: auto; z-index: 9999;\r\n }\r\n .ngxsmk-options-panel ul { list-style: none; padding: 4px; margin: 0; }\r\n .ngxsmk-options-panel li { padding: 8px 12px; border-radius: 4px; cursor: pointer; }\r\n .ngxsmk-options-panel li:hover { background-color: var(--datepicker-hover-background, #f0f0f0); }\r\n .ngxsmk-options-panel li.selected {\r\n background-color: var(--datepicker-primary-color, #3880ff); color: var(--datepicker-primary-contrast, #fff);\r\n }\r\n `],\r\n})\r\nexport class CustomSelectComponent {\r\n @Input() options: { label: string; value: any }[] = [];\r\n @Input() value: any;\r\n @Output() valueChange = new EventEmitter<any>();\r\n public isOpen = false;\r\n\r\n private readonly elementRef: ElementRef = inject(ElementRef);\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: MouseEvent): void {\r\n if (!this.elementRef.nativeElement.contains(event.target)) this.isOpen = false;\r\n }\r\n\r\n get displayValue(): string {\r\n const selectedOption = this.options.find((opt) => opt.value === this.value);\r\n return selectedOption ? selectedOption.label : '';\r\n }\r\n\r\n toggleDropdown(): void {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n selectOption(option: { label: string; value: any }): void {\r\n this.value = option.value;\r\n this.valueChange.emit(this.value);\r\n this.isOpen = false;\r\n }\r\n}\r\n\r\nexport type DateInput = Date | string | { toDate: () => Date; _isAMomentObject?: boolean; $d?: Date };\r\n\r\nexport interface DateRange {\r\n [key: string]: [DateInput, DateInput];\r\n}\r\n\r\n@Component({\r\n selector: 'ngxsmk-datepicker',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, CustomSelectComponent],\r\n template: `\r\n <div class=\"ngxsmk-datepicker-container\">\r\n @if (showRanges && rangesArray.length > 0 && mode === 'range') {\r\n <div class=\"ngxsmk-ranges-container\">\r\n <ul>\r\n @for (range of rangesArray; track range.key) {\r\n <li (click)=\"selectRange(range.value)\">{{ range.key }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n <div class=\"ngxsmk-calendar-container\">\r\n <div class=\"ngxsmk-header\">\r\n <div class=\"ngxsmk-month-year-selects\">\r\n <app-custom-select class=\"month-select\" [options]=\"monthOptions\"\r\n [(value)]=\"currentMonth\"></app-custom-select>\r\n <app-custom-select class=\"year-select\" [options]=\"yearOptions\" [(value)]=\"currentYear\"></app-custom-select>\r\n </div>\r\n <div class=\"ngxsmk-nav-buttons\">\r\n <button type=\"button\" class=\"ngxsmk-nav-button\" (click)=\"changeMonth(-1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M328 112L184 256l144 144\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"ngxsmk-nav-button\" (click)=\"changeMonth(1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M184 112l144 144-144 144\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"ngxsmk-days-grid-wrapper\">\r\n <div class=\"ngxsmk-days-grid\">\r\n @for (day of weekDays; track day) {\r\n <div class=\"ngxsmk-day-name\">{{ day }}</div>\r\n }\r\n @for (day of daysInMonth; track $index) {\r\n <div class=\"ngxsmk-day-cell\"\r\n [class.empty]=\"!day\" [class.disabled]=\"isDateDisabled(day)\" [class.today]=\"isSameDay(day, today)\"\r\n [class.selected]=\"mode === 'single' && isSameDay(day, selectedDate)\"\r\n [class.start-date]=\"mode === 'range' && isSameDay(day, startDate)\"\r\n [class.end-date]=\"mode === 'range' && isSameDay(day, endDate)\"\r\n [class.in-range]=\"mode === 'range' && isInRange(day)\"\r\n [class.preview-range]=\"isPreviewInRange(day)\"\r\n (click)=\"onDateClick(day)\" (mouseenter)=\"onDateHover(day)\">\r\n @if (day) {\r\n <div class=\"ngxsmk-day-number\">{{ day | date : 'd' }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n\r\n @if (showTime) {\r\n <div class=\"ngxsmk-time-selection\">\r\n <span class=\"ngxsmk-time-label\">Time:</span>\r\n <app-custom-select\r\n class=\"hour-select\"\r\n [options]=\"hourOptions\"\r\n [(value)]=\"currentDisplayHour\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n <span class=\"ngxsmk-time-separator\">:</span>\r\n <app-custom-select\r\n class=\"minute-select\"\r\n [options]=\"minuteOptions\"\r\n [(value)]=\"currentMinute\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n <app-custom-select\r\n class=\"ampm-select\"\r\n [options]=\"ampmOptions\"\r\n [(value)]=\"isPm\"\r\n (valueChange)=\"onTimeChange()\"\r\n ></app-custom-select>\r\n </div>\r\n }\r\n\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --datepicker-primary-color: #6d28d9; --datepicker-primary-contrast: #ffffff;\r\n --datepicker-range-background: #f5f3ff; --datepicker-background: #ffffff;\r\n --datepicker-text-color: #222428; --datepicker-subtle-text-color: #9ca3af;\r\n --datepicker-border-color: #e9e9e9; --datepicker-hover-background: #f0f0f0;\r\n }\r\n :host(.dark-theme) {\r\n --datepicker-range-background: rgba(139, 92, 246, 0.2); --datepicker-background: #1f2937;\r\n --datepicker-text-color: #d1d5db; --datepicker-subtle-text-color: #6b7280;\r\n --datepicker-border-color: #4b5563; --datepicker-hover-background: #374151;\r\n }\r\n .ngxsmk-datepicker-container { display: flex; }\r\n .ngxsmk-calendar-container {\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n border-radius: 10px; padding: 16px; background: var(--datepicker-background);\r\n }\r\n .ngxsmk-header {\r\n display: flex; justify-content: space-between; align-items: center;\r\n margin-bottom: 12px; position: relative; z-index: 2; gap: 5px;\r\n }\r\n .ngxsmk-month-year-selects { display: flex; gap: 5px; }\r\n .ngxsmk-month-year-selects app-custom-select.month-select { --custom-select-width: 120px; }\r\n .ngxsmk-month-year-selects app-custom-select.year-select { --custom-select-width: 90px; }\r\n .ngxsmk-nav-buttons { display: flex; }\r\n .ngxsmk-nav-button {\r\n background: none; border: none; padding: 8px; cursor: pointer; border-radius: 50%;\r\n display: inline-flex; align-items: center; justify-content: center; color: var(--datepicker-text-color);\r\n }\r\n .ngxsmk-nav-button:hover { background-color: var(--datepicker-hover-background); }\r\n .ngxsmk-nav-button svg { width: 18px; height: 18px; }\r\n .ngxsmk-days-grid-wrapper { position: relative; }\r\n .ngxsmk-days-grid {\r\n display: grid; grid-template-columns: repeat(7, 1fr); text-align: center; gap: 0;\r\n }\r\n .ngxsmk-day-name {\r\n font-weight: 600; font-size: 0.8rem; color: var(--datepicker-subtle-text-color); padding: 8px 0;\r\n }\r\n .ngxsmk-day-cell {\r\n position: relative; height: 38px; display: flex; justify-content: center;\r\n align-items: center; cursor: pointer; border-radius: 0;\r\n }\r\n .ngxsmk-day-number {\r\n width: 36px; height: 36px; display: flex; justify-content: center;\r\n align-items: center; border-radius: 50%; color: var(--datepicker-text-color);\r\n position: relative; z-index: 1;\r\n }\r\n .ngxsmk-day-cell:not(.disabled):hover .ngxsmk-day-number {\r\n background-color: var(--datepicker-hover-background); color: var(--datepicker-primary-color);\r\n }\r\n .ngxsmk-day-cell.start-date .ngxsmk-day-number,\r\n .ngxsmk-day-cell.end-date .ngxsmk-day-number,\r\n .ngxsmk-day-cell.selected .ngxsmk-day-number {\r\n background-color: var(--datepicker-primary-color); color: var(--datepicker-primary-contrast);\r\n }\r\n .ngxsmk-day-cell.in-range, .ngxsmk-day-cell.start-date,\r\n .ngxsmk-day-cell.end-date, .ngxsmk-day-cell.preview-range {\r\n background-color: var(--datepicker-range-background);\r\n }\r\n .ngxsmk-day-cell.start-date { border-top-left-radius: 100%; border-bottom-left-radius: 100%; }\r\n .ngxsmk-day-cell.end-date { border-top-right-radius: 100%; border-bottom-right-radius: 100%; }\r\n .ngxsmk-day-cell.start-date.end-date { border-radius: 50px; }\r\n .ngxsmk-day-cell.disabled {\r\n background-color: transparent !important; color: #4b5563;\r\n cursor: not-allowed; pointer-events: none; opacity: 0.5;\r\n }\r\n .ngxsmk-day-cell.today .ngxsmk-day-number { border: 1px solid var(--datepicker-primary-color); }\r\n .ngxsmk-ranges-container {\r\n width: 180px; padding: 16px; border-right: 1px solid var(--datepicker-border-color);\r\n background: var(--datepicker-background);\r\n }\r\n .ngxsmk-ranges-container ul { list-style: none; padding: 0; margin: 0; }\r\n .ngxsmk-ranges-container li {\r\n padding: 10px; margin-bottom: 8px; border-radius: 6px; cursor: pointer; color: var(--datepicker-text-color);\r\n }\r\n .ngxsmk-ranges-container li:hover { background-color: var(--datepicker-hover-background); }\r\n .ngxsmk-time-selection {\r\n display: flex; align-items: center; justify-content: center; gap: 4px;\r\n margin-top: 16px; padding-top: 12px; border-top: 1px solid var(--datepicker-border-color);\r\n }\r\n .ngxsmk-time-label { font-size: 0.9rem; color: var(--datepicker-subtle-text-color); margin-right: 4px; }\r\n .ngxsmk-time-selection app-custom-select { --custom-select-width: 60px; height: 30px; }\r\n .ngxsmk-time-selection app-custom-select.ampm-select { --custom-select-width: 70px; }\r\n .ngxsmk-time-separator { font-weight: 600; font-size: 1.1rem; color: var(--datepicker-text-color); }\r\n `],\r\n})\r\nexport class NgxsmkDatepickerComponent implements OnInit, OnChanges {\r\n @Input() mode: 'single' | 'range' = 'single';\r\n @Input() isInvalidDate: (date: Date) => boolean = () => false;\r\n @Input() showRanges: boolean = true;\r\n @Input() showTime: boolean = false;\r\n @Input() minuteInterval: number = 1;\r\n @Input() value: Date | { start: Date, end: Date } | null = null;\r\n\r\n private _locale: string = 'en-US';\r\n @Input() set locale(value: string) { this._locale = value; }\r\n get locale(): string { return this._locale; }\r\n\r\n @Input() theme: 'light' | 'dark' = 'light';\r\n @HostBinding('class.dark-theme') get isDarkMode() { return this.theme === 'dark'; }\r\n @Output() valueChange = new EventEmitter<Date | { start: Date; end: Date }>();\r\n\r\n private _minDate: Date | null = null;\r\n @Input() set minDate(value: DateInput | null) { this._minDate = this._normalizeDate(value); }\r\n\r\n private _maxDate: Date | null = null;\r\n @Input() set maxDate(value: DateInput | null) { this._maxDate = this._normalizeDate(value); }\r\n\r\n private _ranges: { [key: string]: [Date, Date] } | null = null;\r\n @Input() set ranges(value: DateRange | null) {\r\n if (!value) {\r\n this._ranges = null;\r\n } else {\r\n this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {\r\n const start = this._normalizeDate(dates[0]);\r\n const end = this._normalizeDate(dates[1]);\r\n if (start && end) acc[key] = [start, end];\r\n return acc;\r\n }, {} as { [key: string]: [Date, Date] });\r\n }\r\n this.updateRangesArray();\r\n }\r\n\r\n public currentDate: Date = new Date();\r\n public daysInMonth: (Date | null)[] = [];\r\n public weekDays: string[] = [];\r\n public readonly today: Date = new Date();\r\n public selectedDate: Date | null = null;\r\n public startDate: Date | null = null;\r\n public endDate: Date | null = null;\r\n public hoveredDate: Date | null = null;\r\n public rangesArray: { key: string; value: [Date, Date] }[] = [];\r\n\r\n private _currentMonth: number = this.currentDate.getMonth();\r\n private _currentYear: number = this.currentDate.getFullYear();\r\n\r\n public monthOptions: { label: string; value: number }[] = [];\r\n public yearOptions: { label: string; value: number }[] = [];\r\n private firstDayOfWeek: number = 0;\r\n\r\n public currentHour: number = 0;\r\n public currentMinute: number = 0;\r\n public currentDisplayHour: number = 12;\r\n public isPm: boolean = false;\r\n\r\n public hourOptions: { label: string; value: number }[] = [];\r\n public minuteOptions: { label: string; value: number }[] = [];\r\n public ampmOptions: { label: string; value: boolean }[] = [\r\n {label: 'AM', value: false},\r\n {label: 'PM', value: true}\r\n ];\r\n\r\n get currentMonth(): number { return this._currentMonth; }\r\n\r\n set currentMonth(month: number) {\r\n if (this._currentMonth !== month) {\r\n this._currentMonth = month;\r\n this.currentDate.setMonth(month);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n get currentYear(): number { return this._currentYear; }\r\n\r\n set currentYear(year: number) {\r\n if (this._currentYear !== year) {\r\n this._currentYear = year;\r\n this.currentDate.setFullYear(year);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n if (this._locale === 'en-US') {\r\n this._locale = navigator.language;\r\n }\r\n\r\n this.today.setHours(0, 0, 0, 0);\r\n this.generateLocaleData();\r\n this.generateTimeOptions();\r\n\r\n if (this.showTime && !this.value) {\r\n const now = new Date();\r\n this.currentHour = now.getHours();\r\n this.currentMinute = Math.floor(now.getMinutes() / this.minuteInterval) * this.minuteInterval;\r\n\r\n if (this.currentMinute === 60) {\r\n this.currentMinute = 0;\r\n this.currentHour = (this.currentHour + 1) % 24;\r\n }\r\n this.update12HourState(this.currentHour);\r\n }\r\n\r\n if (this.value) {\r\n this.initializeValue(this.value);\r\n }\r\n this.generateCalendar();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['locale']) {\r\n this.generateLocaleData();\r\n this.generateCalendar();\r\n }\r\n\r\n if (changes['minuteInterval']) {\r\n this.generateTimeOptions();\r\n this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;\r\n this.onTimeChange();\r\n }\r\n\r\n if (changes['value'] && changes['value'].currentValue !== changes['value'].previousValue) {\r\n this.initializeValue(changes['value'].currentValue);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n private get24Hour(displayHour: number, isPm: boolean): number {\r\n if (isPm) { return displayHour === 12 ? 12 : displayHour + 12; }\r\n return displayHour === 12 ? 0 : displayHour;\r\n }\r\n\r\n private update12HourState(fullHour: number): void {\r\n this.isPm = fullHour >= 12;\r\n this.currentDisplayHour = fullHour % 12 || 12;\r\n }\r\n\r\n private applyCurrentTime(date: Date): Date {\r\n this.currentHour = this.get24Hour(this.currentDisplayHour, this.isPm);\r\n date.setHours(this.currentHour, this.currentMinute, 0, 0);\r\n return date;\r\n }\r\n\r\n private initializeValue(value: Date | { start: Date, end: Date } | null): void {\r\n if (!value) {\r\n this.selectedDate = null; this.startDate = null; this.endDate = null;\r\n return;\r\n }\r\n\r\n let initialDate: Date | null = null;\r\n if (this.mode === 'single' && value instanceof Date) {\r\n this.selectedDate = this._normalizeDate(value); initialDate = this.selectedDate;\r\n } else if (this.mode === 'range' && typeof value === 'object' && 'start' in value && 'end' in value) {\r\n this.startDate = this._normalizeDate(value.start);\r\n this.endDate = this._normalizeDate(value.end);\r\n initialDate = this.startDate;\r\n }\r\n\r\n if (initialDate) {\r\n this.currentDate = new Date(initialDate);\r\n this.currentHour = initialDate.getHours();\r\n this.currentMinute = initialDate.getMinutes();\r\n this.update12HourState(this.currentHour);\r\n this.currentMinute = Math.floor(this.currentMinute / this.minuteInterval) * this.minuteInterval;\r\n }\r\n }\r\n\r\n private _normalizeDate(date: DateInput | null): Date | null {\r\n if (!date) return null;\r\n const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date as any);\r\n if (isNaN(d.getTime())) return null;\r\n return d;\r\n }\r\n\r\n private generateTimeOptions(): void {\r\n this.hourOptions = Array.from({length: 12}).map((_, i) => ({\r\n label: (i + 1).toString().padStart(2, '0'),\r\n value: i + 1,\r\n }));\r\n\r\n this.minuteOptions = [];\r\n for (let i = 0; i < 60; i += this.minuteInterval) {\r\n this.minuteOptions.push({\r\n label: i.toString().padStart(2, '0'),\r\n value: i,\r\n });\r\n }\r\n }\r\n\r\n private generateLocaleData(): void {\r\n this.monthOptions = Array.from({length: 12}).map((_, i) => ({\r\n label: new Date(2024, i, 1).toLocaleDateString(this.locale, {month: 'long'}),\r\n value: i,\r\n }));\r\n\r\n try {\r\n this.firstDayOfWeek = ((new Intl.Locale(this.locale) as any).weekInfo?.firstDay || 0) % 7;\r\n } catch (e) {\r\n this.firstDayOfWeek = 0;\r\n }\r\n\r\n const day = new Date(2024, 0, 7 + this.firstDayOfWeek);\r\n this.weekDays = Array.from({length: 7}).map(() => {\r\n const weekDay = new Date(day).toLocaleDateString(this.locale, {weekday: 'short'});\r\n day.setDate(day.getDate() + 1);\r\n return weekDay;\r\n });\r\n }\r\n\r\n private updateRangesArray(): void {\r\n this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({key, value})) : [];\r\n }\r\n\r\n public selectRange(range: [Date, Date]): void {\r\n this.startDate = this.applyCurrentTime(range[0]);\r\n this.endDate = this.applyCurrentTime(range[1]);\r\n\r\n if (this.startDate && this.endDate) {\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n }\r\n\r\n this.currentDate = new Date(this.startDate);\r\n this.initializeValue({start: this.startDate, end: this.endDate});\r\n this.generateCalendar();\r\n }\r\n\r\n public isDateDisabled(date: Date | null): boolean {\r\n if (!date) return false;\r\n const dateOnly = new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n\r\n if (this._minDate) {\r\n const minDateOnly = new Date(this._minDate.getFullYear(), this._minDate.getMonth(), this._minDate.getDate());\r\n if (dateOnly < minDateOnly) return true;\r\n }\r\n if (this._maxDate) {\r\n const maxDateOnly = new Date(this._maxDate.getFullYear(), this._maxDate.getMonth(), this._maxDate.getDate());\r\n if (dateOnly > maxDateOnly) return true;\r\n }\r\n return this.isInvalidDate(date);\r\n }\r\n\r\n public onTimeChange(): void {\r\n if (this.mode === 'single' && this.selectedDate) {\r\n this.selectedDate = this.applyCurrentTime(this.selectedDate);\r\n this.valueChange.emit(this.selectedDate);\r\n } else if (this.mode === 'range' && this.startDate && this.endDate) {\r\n this.startDate = this.applyCurrentTime(this.startDate);\r\n this.endDate = this.applyCurrentTime(this.endDate);\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n } else if (this.mode === 'range' && this.startDate && !this.endDate) {\r\n this.startDate = this.applyCurrentTime(this.startDate);\r\n }\r\n }\r\n\r\n public onDateClick(day: Date | null): void {\r\n if (!day || this.isDateDisabled(day)) return;\r\n\r\n if (this.mode === 'single') {\r\n this.selectedDate = this.applyCurrentTime(day);\r\n this.valueChange.emit(this.selectedDate);\r\n } else {\r\n if (!this.startDate || (this.startDate && this.endDate)) {\r\n this.startDate = this.applyCurrentTime(day);\r\n this.endDate = null;\r\n } else if (day >= this.startDate) {\r\n this.endDate = this.applyCurrentTime(day);\r\n this.valueChange.emit({start: this.startDate as Date, end: this.endDate as Date});\r\n } else {\r\n this.startDate = this.applyCurrentTime(day);\r\n this.endDate = null;\r\n }\r\n this.hoveredDate = null;\r\n }\r\n\r\n if (this.mode === 'single' && this.selectedDate) {\r\n this.update12HourState(this.selectedDate.getHours());\r\n this.currentMinute = this.selectedDate.getMinutes();\r\n } else if (this.mode === 'range' && this.startDate) {\r\n this.update12HourState(this.startDate.getHours());\r\n this.currentMinute = this.startDate.getMinutes();\r\n }\r\n }\r\n\r\n public onDateHover(day: Date | null): void {\r\n if (this.mode === 'range' && this.startDate && !this.endDate && day) {\r\n this.hoveredDate = day;\r\n }\r\n }\r\n\r\n public isPreviewInRange(day: Date | null): boolean {\r\n if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day) return false;\r\n const start = this.startDate.getTime();\r\n const end = this.hoveredDate.getTime();\r\n const time = day.getTime();\r\n return time > Math.min(start, end) && time < Math.max(start, end);\r\n }\r\n\r\n public generateCalendar(): void {\r\n this.daysInMonth = [];\r\n const year = this.currentDate.getFullYear();\r\n const month = this.currentDate.getMonth();\r\n this._currentMonth = month;\r\n this._currentYear = year;\r\n this.generateDropdownOptions();\r\n const firstDayOfMonth = new Date(year, month, 1);\r\n const lastDayOfMonth = new Date(year, month + 1, 0);\r\n const startDayOfWeek = firstDayOfMonth.getDay();\r\n const emptyCellCount = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;\r\n\r\n for (let i = 0; i < emptyCellCount; i++) {\r\n this.daysInMonth.push(null);\r\n }\r\n for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {\r\n this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));\r\n }\r\n }\r\n\r\n private generateDropdownOptions(): void {\r\n const startYear = this._currentYear - 10;\r\n const endYear = this._currentYear + 10;\r\n this.yearOptions = [];\r\n for (let i = startYear; i <= endYear; i++) {\r\n this.yearOptions.push({label: `${i}`, value: i});\r\n }\r\n }\r\n\r\n public changeMonth(delta: number): void {\r\n this.currentDate.setMonth(this.currentDate.getMonth() + delta);\r\n this.generateCalendar();\r\n }\r\n\r\n public isSameDay(d1: Date | null, d2: Date | null): boolean {\r\n if (!d1 || !d2) return false;\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n }\r\n\r\n public isInRange(d: Date | null): boolean {\r\n if (!d || !this.startDate || !this.endDate) return false;\r\n\r\n const dTime = new Date(d.getFullYear(), d.getMonth(), d.getDate()).getTime();\r\n const startDayTime = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate()).getTime();\r\n const endDayTime = new Date(this.endDate.getFullYear(), this.endDate.getMonth(), this.endDate.getDate()).getTime();\r\n\r\n const startTime = Math.min(startDayTime, endDayTime);\r\n const endTime = Math.max(startDayTime, endDayTime);\r\n\r\n return dTime > startTime && dTime < endTime;\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngxsmk-datepicker\r\n */\r\n\r\nexport * from './lib/ngxsmk-datepicker';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":";;;;;;MAkEa,qBAAqB,CAAA;AAlDlC,IAAA,WAAA,GAAA;QAmDW,IAAA,CAAA,OAAO,GAAoC,EAAE;AAE5C,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,YAAY,EAAO;QACxC,IAAA,CAAA,MAAM,GAAG,KAAK;AAEJ,QAAA,IAAA,CAAA,UAAU,GAAe,MAAM,CAAC,UAAU,CAAC;AAqB7D,IAAA;AAlBC,IAAA,eAAe,CAAC,KAAiB,EAAA;AAC/B,QAAA,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC;AAAE,YAAA,IAAI,CAAC,MAAM,GAAG,KAAK;IAChF;AAEA,IAAA,IAAI,YAAY,GAAA;QACd,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC;QAC3E,OAAO,cAAc,GAAG,cAAc,CAAC,KAAK,GAAG,EAAE;IACnD;IAEA,cAAc,GAAA;AACZ,QAAA,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM;IAC5B;AAEA,IAAA,YAAY,CAAC,MAAqC,EAAA;AAChD,QAAA,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK;QACzB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;AACjC,QAAA,IAAI,CAAC,MAAM,GAAG,KAAK;IACrB;8GA1BW,qBAAqB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAArB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,qBAAqB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,OAAA,EAAA,SAAA,EAAA,KAAA,EAAA,OAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,SAAA,EAAA,EAAA,gBAAA,EAAA,yBAAA,EAAA,EAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EA9CtB,CAAA;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,yoCAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAtBS,YAAY,EAAA,CAAA,EAAA,CAAA,CAAA;;2FA+CX,qBAAqB,EAAA,UAAA,EAAA,CAAA;kBAlDjC,SAAS;AACE,YAAA,IAAA,EAAA,CAAA,EAAA,QAAA,EAAA,mBAAmB,cACjB,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,CAAC,EAAA,QAAA,EACb,CAAA;;;;;;;;;;;;;;;;;;;;;AAqBT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,yoCAAA,CAAA,EAAA;8BA0BQ,OAAO,EAAA,CAAA;sBAAf;gBACQ,KAAK,EAAA,CAAA;sBAAb;gBACS,WAAW,EAAA,CAAA;sBAApB;gBAMD,eAAe,EAAA,CAAA;sBADd,YAAY;uBAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC;;MAwM/B,yBAAyB,CAAA;AA7KtC,IAAA,WAAA,GAAA;QA8KW,IAAA,CAAA,IAAI,GAAuB,QAAQ;AACnC,QAAA,IAAA,CAAA,aAAa,GAA4B,MAAM,KAAK;QACpD,IAAA,CAAA,UAAU,GAAY,IAAI;QAC1B,IAAA,CAAA,QAAQ,GAAY,KAAK;QACzB,IAAA,CAAA,cAAc,GAAW,CAAC;QAC1B,IAAA,CAAA,KAAK,GAA6C,IAAI;QAEvD,IAAA,CAAA,OAAO,GAAW,OAAO;QAIxB,IAAA,CAAA,KAAK,GAAqB,OAAO;AAEhC,QAAA,IAAA,CAAA,WAAW,GAAG,IAAI,YAAY,EAAqC;QAErE,IAAA,CAAA,QAAQ,GAAgB,IAAI;QAG5B,IAAA,CAAA,QAAQ,GAAgB,IAAI;QAG5B,IAAA,CAAA,OAAO,GAA2C,IAAI;AAevD,QAAA,IAAA,CAAA,WAAW,GAAS,IAAI,IAAI,EAAE;QAC9B,IAAA,CAAA,WAAW,GAAoB,EAAE;QACjC,IAAA,CAAA,QAAQ,GAAa,EAAE;AACd,QAAA,IAAA,CAAA,KAAK,GAAS,IAAI,IAAI,EAAE;QACjC,IAAA,CAAA,YAAY,GAAgB,IAAI;QAChC,IAAA,CAAA,SAAS,GAAgB,IAAI;QAC7B,IAAA,CAAA,OAAO,GAAgB,IAAI;QAC3B,IAAA,CAAA,WAAW,GAAgB,IAAI;QAC/B,IAAA,CAAA,WAAW,GAA2C,EAAE;AAEvD,QAAA,IAAA,CAAA,aAAa,GAAW,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;AACnD,QAAA,IAAA,CAAA,YAAY,GAAW,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE;QAEtD,IAAA,CAAA,YAAY,GAAuC,EAAE;QACrD,IAAA,CAAA,WAAW,GAAuC,EAAE;QACnD,IAAA,CAAA,cAAc,GAAW,CAAC;QAE3B,IAAA,CAAA,WAAW,GAAW,CAAC;QACvB,IAAA,CAAA,aAAa,GAAW,CAAC;QACzB,IAAA,CAAA,kBAAkB,GAAW,EAAE;QAC/B,IAAA,CAAA,IAAI,GAAY,KAAK;QAErB,IAAA,CAAA,WAAW,GAAuC,EAAE;QACpD,IAAA,CAAA,aAAa,GAAuC,EAAE;AACtD,QAAA,IAAA,CAAA,WAAW,GAAwC;AACxD,YAAA,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAC;AAC3B,YAAA,EAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI;SAC1B;AAoSF,IAAA;IA3VC,IAAa,MAAM,CAAC,KAAa,EAAA,EAAI,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,CAAC;IAC3D,IAAI,MAAM,KAAa,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IAG5C,IAAqC,UAAU,GAAA,EAAK,OAAO,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC;AAIlF,IAAA,IAAa,OAAO,CAAC,KAAuB,EAAA,EAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;AAG5F,IAAA,IAAa,OAAO,CAAC,KAAuB,EAAA,EAAI,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC;IAG5F,IAAa,MAAM,CAAC,KAAuB,EAAA;QACzC,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;QACrB;aAAO;YACL,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,KAAI;gBAChE,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBACzC,IAAI,KAAK,IAAI,GAAG;oBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC;AACzC,gBAAA,OAAO,GAAG;YACZ,CAAC,EAAE,EAAqC,CAAC;QAC3C;QACA,IAAI,CAAC,iBAAiB,EAAE;IAC1B;IA+BA,IAAI,YAAY,KAAa,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC;IAExD,IAAI,YAAY,CAAC,KAAa,EAAA;AAC5B,QAAA,IAAI,IAAI,CAAC,aAAa,KAAK,KAAK,EAAE;AAChC,YAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,YAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC;YAChC,IAAI,CAAC,gBAAgB,EAAE;QACzB;IACF;IAEA,IAAI,WAAW,KAAa,OAAO,IAAI,CAAC,YAAY,CAAC,CAAC;IAEtD,IAAI,WAAW,CAAC,IAAY,EAAA;AAC1B,QAAA,IAAI,IAAI,CAAC,YAAY,KAAK,IAAI,EAAE;AAC9B,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI;AACxB,YAAA,IAAI,CAAC,WAAW,CAAC,WAAW,CAAC,IAAI,CAAC;YAClC,IAAI,CAAC,gBAAgB,EAAE;QACzB;IACF;IAEA,QAAQ,GAAA;AACN,QAAA,IAAI,IAAI,CAAC,OAAO,KAAK,OAAO,EAAE;AAC5B,YAAA,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC,QAAQ;QACnC;AAEA,QAAA,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC/B,IAAI,CAAC,kBAAkB,EAAE;QACzB,IAAI,CAAC,mBAAmB,EAAE;QAE1B,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;AAChC,YAAA,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE;AACtB,YAAA,IAAI,CAAC,WAAW,GAAG,GAAG,CAAC,QAAQ,EAAE;YACjC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc;AAE7F,YAAA,IAAI,IAAI,CAAC,aAAa,KAAK,EAAE,EAAE;AAC7B,gBAAA,IAAI,CAAC,aAAa,GAAG,CAAC;AACtB,gBAAA,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,CAAC,WAAW,GAAG,CAAC,IAAI,EAAE;YAChD;AACA,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1C;AAEA,QAAA,IAAI,IAAI,CAAC,KAAK,EAAE;AACd,YAAA,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC;QAClC;QACA,IAAI,CAAC,gBAAgB,EAAE;IACzB;AAEA,IAAA,WAAW,CAAC,OAAsB,EAAA;AAChC,QAAA,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE;YACrB,IAAI,CAAC,kBAAkB,EAAE;YACzB,IAAI,CAAC,gBAAgB,EAAE;QACzB;AAEA,QAAA,IAAI,OAAO,CAAC,gBAAgB,CAAC,EAAE;YAC7B,IAAI,CAAC,mBAAmB,EAAE;AAC1B,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc;YAC/F,IAAI,CAAC,YAAY,EAAE;QACrB;AAEA,QAAA,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,aAAa,EAAE;YACxF,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC;YACnD,IAAI,CAAC,gBAAgB,EAAE;QACzB;IACF;IAEQ,SAAS,CAAC,WAAmB,EAAE,IAAa,EAAA;QAClD,IAAI,IAAI,EAAE;AAAE,YAAA,OAAO,WAAW,KAAK,EAAE,GAAG,EAAE,GAAG,WAAW,GAAG,EAAE;QAAE;QAC/D,OAAO,WAAW,KAAK,EAAE,GAAG,CAAC,GAAG,WAAW;IAC7C;AAEQ,IAAA,iBAAiB,CAAC,QAAgB,EAAA;AACxC,QAAA,IAAI,CAAC,IAAI,GAAG,QAAQ,IAAI,EAAE;QAC1B,IAAI,CAAC,kBAAkB,GAAG,QAAQ,GAAG,EAAE,IAAI,EAAE;IAC/C;AAEQ,IAAA,gBAAgB,CAAC,IAAU,EAAA;AACjC,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,kBAAkB,EAAE,IAAI,CAAC,IAAI,CAAC;AACrE,QAAA,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC;AACzD,QAAA,OAAO,IAAI;IACb;AAEQ,IAAA,eAAe,CAAC,KAA+C,EAAA;QACrE,IAAI,CAAC,KAAK,EAAE;AACV,YAAA,IAAI,CAAC,YAAY,GAAG,IAAI;AAAE,YAAA,IAAI,CAAC,SAAS,GAAG,IAAI;AAAE,YAAA,IAAI,CAAC,OAAO,GAAG,IAAI;YACpE;QACF;QAEA,IAAI,WAAW,GAAgB,IAAI;QACnC,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,YAAY,IAAI,EAAE;YACnD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC;AAAE,YAAA,WAAW,GAAG,IAAI,CAAC,YAAY;QACjF;AAAO,aAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,IAAI,KAAK,IAAI,KAAK,EAAE;YACnG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,CAAC;YACjD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,GAAG,CAAC;AAC7C,YAAA,WAAW,GAAG,IAAI,CAAC,SAAS;QAC9B;QAEA,IAAI,WAAW,EAAE;YACf,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC;AACxC,YAAA,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,QAAQ,EAAE;AACzC,YAAA,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,UAAU,EAAE;AAC7C,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;AACxC,YAAA,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC,cAAc;QACjG;IACF;AAEQ,IAAA,cAAc,CAAC,IAAsB,EAAA;AAC3C,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI;QACtB,MAAM,CAAC,GAAG,CAAC,IAAI,YAAY,IAAI,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,GAAG,IAAI,IAAI,CAAC,IAAW,CAAC;AACnF,QAAA,IAAI,KAAK,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC;AAAE,YAAA,OAAO,IAAI;AACnC,QAAA,OAAO,CAAC;IACV;IAEQ,mBAAmB,GAAA;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,EAAE,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM;AACzD,YAAA,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;YAC1C,KAAK,EAAE,CAAC,GAAG,CAAC;AACb,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI,CAAC,aAAa,GAAG,EAAE;AACvB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,cAAc,EAAE;AAChD,YAAA,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBACtB,KAAK,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC;AACpC,gBAAA,KAAK,EAAE,CAAC;AACT,aAAA,CAAC;QACJ;IACF;IAEQ,kBAAkB,GAAA;QACxB,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,EAAE,EAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM;YAC1D,KAAK,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,KAAK,EAAE,MAAM,EAAC,CAAC;AAC5E,YAAA,KAAK,EAAE,CAAC;AACT,SAAA,CAAC,CAAC;AAEH,QAAA,IAAI;YACF,IAAI,CAAC,cAAc,GAAG,CAAE,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAS,CAAC,QAAQ,EAAE,QAAQ,IAAI,CAAC,IAAI,CAAC;QAC3F;QAAE,OAAO,CAAC,EAAE;AACV,YAAA,IAAI,CAAC,cAAc,GAAG,CAAC;QACzB;AAEA,QAAA,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC;AACtD,QAAA,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC,IAAI,CAAC,EAAC,MAAM,EAAE,CAAC,EAAC,CAAC,CAAC,GAAG,CAAC,MAAK;YAC/C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAC,OAAO,EAAE,OAAO,EAAC,CAAC;YACjF,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;AAC9B,YAAA,OAAO,OAAO;AAChB,QAAA,CAAC,CAAC;IACJ;IAEQ,iBAAiB,GAAA;AACvB,QAAA,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,MAAM,EAAC,GAAG,EAAE,KAAK,EAAC,CAAC,CAAC,GAAG,EAAE;IAC3G;AAEO,IAAA,WAAW,CAAC,KAAmB,EAAA;AACpC,QAAA,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAChD,QAAA,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAE9C,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE;AAClC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,SAAiB,EAAE,GAAG,EAAE,IAAI,CAAC,OAAe,EAAC,CAAC;QACnF;QAEA,IAAI,CAAC,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;AAC3C,QAAA,IAAI,CAAC,eAAe,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,EAAC,CAAC;QAChE,IAAI,CAAC,gBAAgB,EAAE;IACzB;AAEO,IAAA,cAAc,CAAC,IAAiB,EAAA;AACrC,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,KAAK;QACvB,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC;AAE9E,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC5G,IAAI,QAAQ,GAAG,WAAW;AAAE,gBAAA,OAAO,IAAI;QACzC;AACA,QAAA,IAAI,IAAI,CAAC,QAAQ,EAAE;YACjB,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC;YAC5G,IAAI,QAAQ,GAAG,WAAW;AAAE,gBAAA,OAAO,IAAI;QACzC;AACA,QAAA,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IACjC;IAEO,YAAY,GAAA;QACjB,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE;YAC/C,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,YAAY,CAAC;YAC5D,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAC1C;AAAO,aAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,EAAE;YAClE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC;YACtD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC;AAClD,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,SAAiB,EAAE,GAAG,EAAE,IAAI,CAAC,OAAe,EAAC,CAAC;QACnF;AAAO,aAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE;YACnE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC;QACxD;IACF;AAEO,IAAA,WAAW,CAAC,GAAgB,EAAA;QACjC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC;YAAE;AAEtC,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE;YAC1B,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;YAC9C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC;QAC1C;aAAO;AACL,YAAA,IAAI,CAAC,IAAI,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE;gBACvD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;AAC3C,gBAAA,IAAI,CAAC,OAAO,GAAG,IAAI;YACrB;AAAO,iBAAA,IAAI,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE;gBAChC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;AACzC,gBAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,IAAI,CAAC,SAAiB,EAAE,GAAG,EAAE,IAAI,CAAC,OAAe,EAAC,CAAC;YACnF;iBAAO;gBACL,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC;AAC3C,gBAAA,IAAI,CAAC,OAAO,GAAG,IAAI;YACrB;AACA,YAAA,IAAI,CAAC,WAAW,GAAG,IAAI;QACzB;QAEA,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,YAAY,EAAE;YAC/C,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YACpD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE;QACrD;aAAO,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE;YAClD,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC;YACjD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;QAClD;IACF;AAEO,IAAA,WAAW,CAAC,GAAgB,EAAA;AACjC,QAAA,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,GAAG,EAAE;AACnE,YAAA,IAAI,CAAC,WAAW,GAAG,GAAG;QACxB;IACF;AAEO,IAAA,gBAAgB,CAAC,GAAgB,EAAA;QACtC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,KAAK;QACvG,MAAM,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE;QACtC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,EAAE;QAC1B,OAAO,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC;IACnE;IAEO,gBAAgB,GAAA;AACrB,QAAA,IAAI,CAAC,WAAW,GAAG,EAAE;QACrB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,WAAW,EAAE;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE;AACzC,QAAA,IAAI,CAAC,aAAa,GAAG,KAAK;AAC1B,QAAA,IAAI,CAAC,YAAY,GAAG,IAAI;QACxB,IAAI,CAAC,uBAAuB,EAAE;QAC9B,MAAM,eAAe,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AAChD,QAAA,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,CAAC,CAAC;AACnD,QAAA,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,EAAE;AAC/C,QAAA,MAAM,cAAc,GAAG,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,GAAG,CAAC,IAAI,CAAC;AAErE,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,cAAc,EAAE,CAAC,EAAE,EAAE;AACvC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;QAC7B;AACA,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,cAAc,CAAC,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;YAClD,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACtE;IACF;IAEQ,uBAAuB,GAAA;AAC7B,QAAA,MAAM,SAAS,GAAG,IAAI,CAAC,YAAY,GAAG,EAAE;AACxC,QAAA,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,GAAG,EAAE;AACtC,QAAA,IAAI,CAAC,WAAW,GAAG,EAAE;AACrB,QAAA,KAAK,IAAI,CAAC,GAAG,SAAS,EAAE,CAAC,IAAI,OAAO,EAAE,CAAC,EAAE,EAAE;AACzC,YAAA,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAC,KAAK,EAAE,CAAA,EAAG,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAC,CAAC;QAClD;IACF;AAEO,IAAA,WAAW,CAAC,KAAa,EAAA;AAC9B,QAAA,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,GAAG,KAAK,CAAC;QAC9D,IAAI,CAAC,gBAAgB,EAAE;IACzB;IAEO,SAAS,CAAC,EAAe,EAAE,EAAe,EAAA;AAC/C,QAAA,IAAI,CAAC,EAAE,IAAI,CAAC,EAAE;AAAE,YAAA,OAAO,KAAK;QAC5B,QACE,EAAE,CAAC,WAAW,EAAE,KAAK,EAAE,CAAC,WAAW,EAAE;AACrC,YAAA,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,QAAQ,EAAE;YAC/B,EAAE,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE;IAEjC;AAEO,IAAA,SAAS,CAAC,CAAc,EAAA;QAC7B,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,OAAO;AAAE,YAAA,OAAO,KAAK;QAExD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;AAC5E,QAAA,MAAM,YAAY,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;AAC1H,QAAA,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE;QAElH,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC;QACpD,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,YAAY,EAAE,UAAU,CAAC;AAElD,QAAA,OAAO,KAAK,GAAG,SAAS,IAAI,KAAK,GAAG,OAAO;IAC7C;8GAnWW,yBAAyB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,SAAA,EAAA,CAAA,CAAA;AAAzB,IAAA,SAAA,IAAA,CAAA,IAAA,GAAA,EAAA,CAAA,oBAAA,CAAA,EAAA,UAAA,EAAA,QAAA,EAAA,OAAA,EAAA,QAAA,EAAA,IAAA,EAAA,yBAAyB,EAAA,YAAA,EAAA,IAAA,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,aAAA,EAAA,eAAA,EAAA,UAAA,EAAA,YAAA,EAAA,QAAA,EAAA,UAAA,EAAA,cAAA,EAAA,gBAAA,EAAA,KAAA,EAAA,OAAA,EAAA,MAAA,EAAA,QAAA,EAAA,KAAA,EAAA,OAAA,EAAA,OAAA,EAAA,SAAA,EAAA,OAAA,EAAA,SAAA,EAAA,MAAA,EAAA,QAAA,EAAA,EAAA,OAAA,EAAA,EAAA,WAAA,EAAA,aAAA,EAAA,EAAA,IAAA,EAAA,EAAA,UAAA,EAAA,EAAA,kBAAA,EAAA,iBAAA,EAAA,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,QAAA,EAAA,EAAA,EAAA,QAAA,EAzK1B,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFT,EAAA,CAAA,EAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,u2HAAA,CAAA,EAAA,YAAA,EAAA,CAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAnFS,YAAY,EAAA,EAAA,EAAA,IAAA,EAAA,UAAA,EAAA,IAAA,EAAE,WAAW,EAAA,EAAA,EAAA,IAAA,EAAA,WAAA,EAAA,IAAA,EAtCxB,qBAAqB,EAAA,QAAA,EAAA,mBAAA,EAAA,MAAA,EAAA,CAAA,SAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAAA,CAAA,aAAA,CAAA,EAAA,EAAA,EAAA,IAAA,EAAA,MAAA,EAAA,IAAA,EAAA,EAAA,CAAA,QAAA,EAAA,IAAA,EAAA,MAAA,EAAA,CAAA,EAAA,CAAA,CAAA;;2FAgNrB,yBAAyB,EAAA,UAAA,EAAA,CAAA;kBA7KrC,SAAS;+BACE,mBAAmB,EAAA,UAAA,EACjB,IAAI,EAAA,OAAA,EACP,CAAC,YAAY,EAAE,WAAW,EAAE,qBAAqB,CAAC,EAAA,QAAA,EACjD,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkFT,EAAA,CAAA,EAAA,MAAA,EAAA,CAAA,u2HAAA,CAAA,EAAA;8BAwFQ,IAAI,EAAA,CAAA;sBAAZ;gBACQ,aAAa,EAAA,CAAA;sBAArB;gBACQ,UAAU,EAAA,CAAA;sBAAlB;gBACQ,QAAQ,EAAA,CAAA;sBAAhB;gBACQ,cAAc,EAAA,CAAA;sBAAtB;gBACQ,KAAK,EAAA,CAAA;sBAAb;gBAGY,MAAM,EAAA,CAAA;sBAAlB;gBAGQ,KAAK,EAAA,CAAA;sBAAb;gBACoC,UAAU,EAAA,CAAA;sBAA9C,WAAW;uBAAC,kBAAkB;gBACrB,WAAW,EAAA,CAAA;sBAApB;gBAGY,OAAO,EAAA,CAAA;sBAAnB;gBAGY,OAAO,EAAA,CAAA;sBAAnB;gBAGY,MAAM,EAAA,CAAA;sBAAlB;;;ACzSH;;AAEG;;ACFH;;AAEG;;;;"}
|
package/index.d.ts
CHANGED
|
@@ -1,26 +1,18 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { EventEmitter,
|
|
2
|
+
import { EventEmitter, OnInit, OnChanges, SimpleChanges } from '@angular/core';
|
|
3
3
|
|
|
4
4
|
declare class CustomSelectComponent {
|
|
5
|
-
private readonly elementRef;
|
|
6
|
-
/** The list of available options to display in the dropdown. */
|
|
7
5
|
options: {
|
|
8
6
|
label: string;
|
|
9
7
|
value: any;
|
|
10
8
|
}[];
|
|
11
|
-
/** The currently selected value. */
|
|
12
9
|
value: any;
|
|
13
|
-
/** Emits the new value when an option is selected. */
|
|
14
10
|
valueChange: EventEmitter<any>;
|
|
15
11
|
isOpen: boolean;
|
|
16
|
-
|
|
17
|
-
/** Closes the dropdown when a click occurs outside the component boundary. */
|
|
12
|
+
private readonly elementRef;
|
|
18
13
|
onDocumentClick(event: MouseEvent): void;
|
|
19
|
-
/** Gets the display label for the currently selected value. */
|
|
20
14
|
get displayValue(): string;
|
|
21
|
-
/** Toggles the visibility of the dropdown panel. */
|
|
22
15
|
toggleDropdown(): void;
|
|
23
|
-
/** Handles the selection of a new option. */
|
|
24
16
|
selectOption(option: {
|
|
25
17
|
label: string;
|
|
26
18
|
value: any;
|
|
@@ -37,42 +29,29 @@ interface DateRange {
|
|
|
37
29
|
[key: string]: [DateInput, DateInput];
|
|
38
30
|
}
|
|
39
31
|
declare class NgxsmkDatepickerComponent implements OnInit, OnChanges {
|
|
40
|
-
private readonly platformId;
|
|
41
|
-
/** Sets the selection mode: 'single' date or 'range' selection. */
|
|
42
32
|
mode: 'single' | 'range';
|
|
43
|
-
/** A function to programmatically disable specific dates. Returns true if the date should be disabled. */
|
|
44
33
|
isInvalidDate: (date: Date) => boolean;
|
|
45
|
-
/** If true, displays the predefined ranges panel when in 'range' mode. */
|
|
46
34
|
showRanges: boolean;
|
|
47
|
-
/** If true, displays the time selection controls (hour/minute). */
|
|
48
35
|
showTime: boolean;
|
|
49
|
-
/** Sets the minute selection step/interval (e.g., 5, 15, 30). */
|
|
50
36
|
minuteInterval: number;
|
|
51
|
-
/** The initial selected date or date range. Accepts Date, or { start: Date, end: Date }. */
|
|
52
37
|
value: Date | {
|
|
53
38
|
start: Date;
|
|
54
39
|
end: Date;
|
|
55
40
|
} | null;
|
|
56
41
|
private _locale;
|
|
57
|
-
/** Sets the locale for language and regional formatting (e.g., 'en-US', 'de-DE'). */
|
|
58
42
|
set locale(value: string);
|
|
59
43
|
get locale(): string;
|
|
60
|
-
/** Controls the visual theme: 'light' or 'dark'. */
|
|
61
44
|
theme: 'light' | 'dark';
|
|
62
45
|
get isDarkMode(): boolean;
|
|
63
|
-
/** Emits the newly selected date or date range. */
|
|
64
46
|
valueChange: EventEmitter<Date | {
|
|
65
47
|
start: Date;
|
|
66
48
|
end: Date;
|
|
67
49
|
}>;
|
|
68
50
|
private _minDate;
|
|
69
|
-
/** The earliest selectable date. */
|
|
70
51
|
set minDate(value: DateInput | null);
|
|
71
52
|
private _maxDate;
|
|
72
|
-
/** The latest selectable date. */
|
|
73
53
|
set maxDate(value: DateInput | null);
|
|
74
54
|
private _ranges;
|
|
75
|
-
/** An object of predefined date ranges for quick selection. */
|
|
76
55
|
set ranges(value: DateRange | null);
|
|
77
56
|
currentDate: Date;
|
|
78
57
|
daysInMonth: (Date | null)[];
|
|
@@ -113,50 +92,30 @@ declare class NgxsmkDatepickerComponent implements OnInit, OnChanges {
|
|
|
113
92
|
label: string;
|
|
114
93
|
value: boolean;
|
|
115
94
|
}[];
|
|
116
|
-
constructor(platformId: Object);
|
|
117
95
|
get currentMonth(): number;
|
|
118
96
|
set currentMonth(month: number);
|
|
119
97
|
get currentYear(): number;
|
|
120
98
|
set currentYear(year: number);
|
|
121
99
|
ngOnInit(): void;
|
|
122
100
|
ngOnChanges(changes: SimpleChanges): void;
|
|
123
|
-
/** Converts the displayed 12h time (currentDisplayHour + isPm) into the 24h internal time (currentHour). */
|
|
124
101
|
private get24Hour;
|
|
125
|
-
/** Updates the display time variables (12h format and AM/PM state) from the 24h internal time. */
|
|
126
102
|
private update12HourState;
|
|
127
|
-
/** Applies the currently selected hour and minute to a given date object. */
|
|
128
103
|
private applyCurrentTime;
|
|
129
|
-
/** Initializes selection state and time controls from the provided input value. */
|
|
130
104
|
private initializeValue;
|
|
131
|
-
/** Normalizes a date input to a Date object, keeping time information. */
|
|
132
105
|
private _normalizeDate;
|
|
133
|
-
/** Generates options for the hour and minute selectors based on the interval. */
|
|
134
106
|
private generateTimeOptions;
|
|
135
|
-
/** Generates locale-dependent month and weekday names. */
|
|
136
107
|
private generateLocaleData;
|
|
137
|
-
/** Populates the internal array of predefined ranges. */
|
|
138
108
|
private updateRangesArray;
|
|
139
|
-
/** Handles selection of a predefined date range. */
|
|
140
109
|
selectRange(range: [Date, Date]): void;
|
|
141
|
-
/** Checks if a specific date should be disabled based on minDate, maxDate, or custom function. */
|
|
142
110
|
isDateDisabled(date: Date | null): boolean;
|
|
143
|
-
/** Updates the time component of the selected date(s) when hour/minute selectors change. */
|
|
144
111
|
onTimeChange(): void;
|
|
145
|
-
/** Handles the click event on a calendar day cell. */
|
|
146
112
|
onDateClick(day: Date | null): void;
|
|
147
|
-
/** Handles hover events for range preview when only the start date is selected. */
|
|
148
113
|
onDateHover(day: Date | null): void;
|
|
149
|
-
/** Checks if a date is within the range being previewed (during hover). */
|
|
150
114
|
isPreviewInRange(day: Date | null): boolean;
|
|
151
|
-
/** Generates the calendar grid for the currently active month. */
|
|
152
115
|
generateCalendar(): void;
|
|
153
|
-
/** Generates month and year options for dropdowns. */
|
|
154
116
|
private generateDropdownOptions;
|
|
155
|
-
/** Moves the calendar view forward or backward by one month. */
|
|
156
117
|
changeMonth(delta: number): void;
|
|
157
|
-
/** Utility function to check if two dates represent the same day (ignoring time). */
|
|
158
118
|
isSameDay(d1: Date | null, d2: Date | null): boolean;
|
|
159
|
-
/** Checks if a date is strictly between the start and end of a selected range (ignoring time). */
|
|
160
119
|
isInRange(d: Date | null): boolean;
|
|
161
120
|
static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkDatepickerComponent, never>;
|
|
162
121
|
static ɵcmp: i0.ɵɵComponentDeclaration<NgxsmkDatepickerComponent, "ngxsmk-datepicker", never, { "mode": { "alias": "mode"; "required": false; }; "isInvalidDate": { "alias": "isInvalidDate"; "required": false; }; "showRanges": { "alias": "showRanges"; "required": false; }; "showTime": { "alias": "showTime"; "required": false; }; "minuteInterval": { "alias": "minuteInterval"; "required": false; }; "value": { "alias": "value"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "minDate": { "alias": "minDate"; "required": false; }; "maxDate": { "alias": "maxDate"; "required": false; }; "ranges": { "alias": "ranges"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|