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