@luftborn/custom-elements 2.8.1 → 2.8.3
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/demo/index.js +680 -2852
- package/demo/index.min.js +679 -2851
- package/demo/index.min.js.map +1 -1
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.d.ts +48 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.js +333 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.js.map +1 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.d.ts +1 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.js +5 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.js.map +1 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerUtils.d.ts +6 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerUtils.js +45 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerUtils.js.map +1 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/DatepickerTranslations.d.ts +2 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/DatepickerTranslations.js +194 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomDatepicker/DatepickerTranslations.js.map +1 -0
- package/dist/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.d.ts +7 -6
- package/dist/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.js +27 -59
- package/dist/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.js.map +1 -1
- package/package.json +2 -6
- package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepicker.ts +363 -0
- package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerStyles.ts +101 -0
- package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/CustomDatepickerUtils.ts +44 -0
- package/src/elements/CustomFormatDateFieldElement/CustomDatepicker/DatepickerTranslations.ts +188 -0
- package/src/elements/CustomFormatDateFieldElement/CustomFormatDateFieldElement.ts +30 -67
|
@@ -0,0 +1,363 @@
|
|
|
1
|
+
import { CustomDatepickerStyles } from "./CustomDatepickerStyles";
|
|
2
|
+
import { defaultDateFormat, formatDate, isMobileDevice, supportedDateFormats } from "./CustomDatepickerUtils";
|
|
3
|
+
import { GetMonths, GetWeekdays } from "./DatepickerTranslations";
|
|
4
|
+
|
|
5
|
+
type CustomDatepickerOptions = {
|
|
6
|
+
input: HTMLInputElement;
|
|
7
|
+
dateFormat: string;
|
|
8
|
+
language?: string;
|
|
9
|
+
otherTriggers?: HTMLElement[];
|
|
10
|
+
parentElement?: ShadowRoot | HTMLElement;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default class CustomDatepicker {
|
|
14
|
+
private input: HTMLInputElement;
|
|
15
|
+
private otherTriggers: HTMLElement[];
|
|
16
|
+
private parentElement: ShadowRoot | HTMLElement;
|
|
17
|
+
|
|
18
|
+
private datepicker: HTMLElement;
|
|
19
|
+
private header: HTMLElement;
|
|
20
|
+
private monthYear: HTMLElement;
|
|
21
|
+
private selectNextMonth: HTMLElement;
|
|
22
|
+
private selectPrevMonth: HTMLElement;
|
|
23
|
+
private weekdays: HTMLElement;
|
|
24
|
+
private days: HTMLElement;
|
|
25
|
+
private selectMonthYear: HTMLElement;
|
|
26
|
+
private selectDate: HTMLElement;
|
|
27
|
+
private currentDate: Date;
|
|
28
|
+
private currentMonth: number;
|
|
29
|
+
private currentYear: number;
|
|
30
|
+
private selectedDate: Date;
|
|
31
|
+
private selectedMonth: number;
|
|
32
|
+
private selectedYear: number;
|
|
33
|
+
private selectedDay: number;
|
|
34
|
+
private firstDayOfMonth: Date;
|
|
35
|
+
private lastDayOfMonth: Date;
|
|
36
|
+
private firstDay: number;
|
|
37
|
+
private lastDay: number;
|
|
38
|
+
|
|
39
|
+
private months: string[] = [];
|
|
40
|
+
private daysOfWeek: string[] = [];
|
|
41
|
+
|
|
42
|
+
private dateFormat: string;
|
|
43
|
+
|
|
44
|
+
constructor(options: CustomDatepickerOptions) {
|
|
45
|
+
this.input = options.input;
|
|
46
|
+
this.dateFormat = supportedDateFormats.includes(options.dateFormat) ? options.dateFormat : defaultDateFormat;
|
|
47
|
+
this.otherTriggers = options.otherTriggers || [];
|
|
48
|
+
this.parentElement = options.parentElement;
|
|
49
|
+
|
|
50
|
+
this.currentDate = new Date();
|
|
51
|
+
this.currentMonth = this.currentDate.getMonth();
|
|
52
|
+
this.currentYear = this.currentDate.getFullYear();
|
|
53
|
+
this.selectedDate = new Date();
|
|
54
|
+
this.selectedMonth = this.selectedDate.getMonth();
|
|
55
|
+
this.selectedYear = this.selectedDate.getFullYear();
|
|
56
|
+
this.selectedDay = this.selectedDate.getDate();
|
|
57
|
+
this.firstDayOfMonth = new Date(this.currentYear, this.currentMonth, 1);
|
|
58
|
+
this.lastDayOfMonth = new Date(this.currentYear, this.currentMonth + 1, 0);
|
|
59
|
+
this.firstDay = this.firstDayOfMonth.getDay();
|
|
60
|
+
this.lastDay = this.lastDayOfMonth.getDate();
|
|
61
|
+
|
|
62
|
+
this.months = GetMonths(options.language);
|
|
63
|
+
this.daysOfWeek = GetWeekdays(options.language, 'short');
|
|
64
|
+
|
|
65
|
+
this.createDatePickerElements();
|
|
66
|
+
this.renderCalendar();
|
|
67
|
+
this.initSelectMonthYear();
|
|
68
|
+
this.addEventListeners();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private createDatePickerElements() {
|
|
72
|
+
this.datepicker = document.createElement('div');
|
|
73
|
+
this.datepicker.classList.add('datepicker');
|
|
74
|
+
this.header = document.createElement('div');
|
|
75
|
+
this.header.classList.add('header');
|
|
76
|
+
this.monthYear = document.createElement('span');
|
|
77
|
+
this.monthYear.classList.add('month-year');
|
|
78
|
+
this.monthYear.onclick = () => this.toggleSelectMonthYear();
|
|
79
|
+
this.selectNextMonth = document.createElement('span');
|
|
80
|
+
this.selectNextMonth.classList.add('next-month');
|
|
81
|
+
this.selectNextMonth.innerHTML = '▶';
|
|
82
|
+
this.selectNextMonth.onclick = () => this.moveMonth(1);
|
|
83
|
+
this.selectPrevMonth = document.createElement('span');
|
|
84
|
+
this.selectPrevMonth.classList.add('prev-month');
|
|
85
|
+
this.selectPrevMonth.innerHTML = '◀';
|
|
86
|
+
this.selectPrevMonth.onclick = () => this.moveMonth(-1);
|
|
87
|
+
this.header.appendChild(this.selectPrevMonth);
|
|
88
|
+
this.header.appendChild(this.monthYear);
|
|
89
|
+
this.header.appendChild(this.selectNextMonth);
|
|
90
|
+
|
|
91
|
+
this.weekdays = document.createElement('div');
|
|
92
|
+
this.weekdays.classList.add('weekdays');
|
|
93
|
+
this.days = document.createElement('div');
|
|
94
|
+
this.days.classList.add('days');
|
|
95
|
+
this.selectMonthYear = document.createElement('div');
|
|
96
|
+
this.selectMonthYear.classList.add('select-month-year');
|
|
97
|
+
this.selectDate = document.createElement('div');
|
|
98
|
+
this.selectDate.classList.add('select-date');
|
|
99
|
+
this.datepicker.appendChild(this.header);
|
|
100
|
+
this.datepicker.appendChild(this.selectDate);
|
|
101
|
+
this.selectDate.appendChild(this.weekdays);
|
|
102
|
+
this.selectDate.appendChild(this.days);
|
|
103
|
+
this.datepicker.appendChild(this.selectMonthYear);
|
|
104
|
+
|
|
105
|
+
let actions = document.createElement('div');
|
|
106
|
+
actions.classList.add('actions');
|
|
107
|
+
this.selectDate.appendChild(actions);
|
|
108
|
+
let cancel = document.createElement('input');
|
|
109
|
+
cancel.type = 'reset';
|
|
110
|
+
cancel.value = 'Cancel';
|
|
111
|
+
cancel.onclick = () => this.showPicker(false);
|
|
112
|
+
actions.appendChild(cancel);
|
|
113
|
+
let today = document.createElement('input');
|
|
114
|
+
today.type = 'reset';
|
|
115
|
+
today.value = 'Today';
|
|
116
|
+
today.onclick = () => this.setDateForToday();
|
|
117
|
+
actions.appendChild(today);
|
|
118
|
+
|
|
119
|
+
if (this.input.parentElement) {
|
|
120
|
+
this.input.parentElement.appendChild(this.datepicker);
|
|
121
|
+
} else {
|
|
122
|
+
document.body.appendChild(this.datepicker);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
this.applyStyles();
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
private applyStyles() {
|
|
129
|
+
const style = document.createElement('style');
|
|
130
|
+
style.innerHTML = CustomDatepickerStyles;
|
|
131
|
+
this.datepicker.appendChild(style);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
private moveMonth(steps: number) {
|
|
135
|
+
let newMonth = this.currentMonth + steps;
|
|
136
|
+
let newYear = this.currentYear;
|
|
137
|
+
if (newMonth < 0) {
|
|
138
|
+
newYear = this.currentYear + Math.floor(newMonth / 12);
|
|
139
|
+
newMonth = 12 + (newMonth % 12);
|
|
140
|
+
} else if (newMonth > 11) {
|
|
141
|
+
newYear = this.currentYear + Math.floor(newMonth / 12);
|
|
142
|
+
newMonth = newMonth % 12;
|
|
143
|
+
}
|
|
144
|
+
this.currentMonth = newMonth;
|
|
145
|
+
this.currentYear = newYear;
|
|
146
|
+
this.firstDayOfMonth = new Date(this.currentYear, this.currentMonth, 1);
|
|
147
|
+
this.lastDayOfMonth = new Date(this.currentYear, this.currentMonth + 1, 0);
|
|
148
|
+
this.firstDay = this.firstDayOfMonth.getDay();
|
|
149
|
+
this.lastDay = this.lastDayOfMonth.getDate();
|
|
150
|
+
this.renderCalendar();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
private renderCalendar() {
|
|
154
|
+
this.monthYear.innerHTML = this.months[this.currentMonth] + ' ' + this.currentYear;
|
|
155
|
+
this.weekdays.innerHTML = '';
|
|
156
|
+
for (let i = 0; i < this.daysOfWeek.length; i++) {
|
|
157
|
+
let span = document.createElement('span');
|
|
158
|
+
span.innerHTML = this.daysOfWeek[i];
|
|
159
|
+
this.weekdays.appendChild(span);
|
|
160
|
+
}
|
|
161
|
+
this.days.innerHTML = '';
|
|
162
|
+
for (let i = 0; i < 42; i++) {
|
|
163
|
+
let span = document.createElement('span');
|
|
164
|
+
if (i < this.firstDay) {
|
|
165
|
+
span.classList.add('day-of-previous-month');
|
|
166
|
+
span.style.color = '#ccc';
|
|
167
|
+
let currentDate = new Date(this.currentYear, this.currentMonth, 0);
|
|
168
|
+
span.innerHTML = (currentDate.getDate() - this.firstDay + i + 1).toString();
|
|
169
|
+
} else if (i < this.lastDay + this.firstDay) {
|
|
170
|
+
span.classList.add('day-of-current-month');
|
|
171
|
+
span.innerHTML = (i - this.firstDay + 1).toString();
|
|
172
|
+
if (i - this.firstDay + 1 === this.selectedDay && this.currentMonth === this.selectedMonth && this.currentYear === this.selectedYear) {
|
|
173
|
+
span.classList.add('selected-day')
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
span.classList.add('day-of-next-month');
|
|
177
|
+
span.style.color = '#ccc';
|
|
178
|
+
span.innerHTML = (i - this.lastDay - this.firstDay + 1).toString();
|
|
179
|
+
}
|
|
180
|
+
span.onclick = () => {
|
|
181
|
+
let moveMonthSteps = 0;
|
|
182
|
+
this.selectedDay = parseInt(span.innerHTML);
|
|
183
|
+
if (span.classList.contains('day-of-previous-month')) {
|
|
184
|
+
this.selectedMonth = this.currentMonth - 1;
|
|
185
|
+
this.selectedYear = this.currentYear;
|
|
186
|
+
moveMonthSteps = -1;
|
|
187
|
+
} else if (span.classList.contains('day-of-current-month')) {
|
|
188
|
+
this.selectedMonth = this.currentMonth;
|
|
189
|
+
this.selectedYear = this.currentYear;
|
|
190
|
+
} else {
|
|
191
|
+
this.selectedMonth = this.currentMonth + 1;
|
|
192
|
+
this.selectedYear = this.currentYear;
|
|
193
|
+
moveMonthSteps = 1;
|
|
194
|
+
}
|
|
195
|
+
this.selectedDate = new Date(this.selectedYear, this.selectedMonth, this.selectedDay);
|
|
196
|
+
let selectedDayElement = this.days.querySelector('.selected-day');
|
|
197
|
+
if (selectedDayElement) {
|
|
198
|
+
selectedDayElement.classList.remove('selected-day');
|
|
199
|
+
}
|
|
200
|
+
span.classList.add('selected-day');
|
|
201
|
+
|
|
202
|
+
const formattedDate = formatDate(this.selectedDate, this.dateFormat);
|
|
203
|
+
this.input.value = formattedDate;
|
|
204
|
+
|
|
205
|
+
this.showPicker(false);
|
|
206
|
+
};
|
|
207
|
+
this.days.appendChild(span);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
this.positionPicker();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
private initSelectMonthYear() {
|
|
214
|
+
this.selectMonthYear.style.display = 'none';
|
|
215
|
+
this.selectMonthYear.style.height = '200px';
|
|
216
|
+
if (isMobileDevice()) {
|
|
217
|
+
this.selectMonthYear.style.height = '300px';
|
|
218
|
+
}
|
|
219
|
+
this.selectMonthYear.innerHTML = '';
|
|
220
|
+
let monthsContainer = document.createElement('div');
|
|
221
|
+
monthsContainer.classList.add('months');
|
|
222
|
+
for (let i = 0; i < this.months.length; i++) {
|
|
223
|
+
let span = document.createElement('span');
|
|
224
|
+
span.innerHTML = this.months[i].substring(0, 3);
|
|
225
|
+
span.classList.add('select-month');
|
|
226
|
+
monthsContainer.appendChild(span);
|
|
227
|
+
span.onclick = () => {
|
|
228
|
+
this.selectedMonth = this.months.findIndex(month => month.substring(0, 3) === span.innerHTML);
|
|
229
|
+
let moveMonthSteps = (this.selectedYear - this.currentYear) * 12 + this.selectedMonth - this.currentMonth;
|
|
230
|
+
this.moveMonth(moveMonthSteps);
|
|
231
|
+
this.hideSelectMonthYear();
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
for (let i = this.currentYear - 100; i < this.currentYear + 100; i++) {
|
|
235
|
+
let year = document.createElement('div');
|
|
236
|
+
year.classList.add('year');
|
|
237
|
+
year.innerHTML = i.toString();
|
|
238
|
+
this.selectMonthYear.appendChild(year);
|
|
239
|
+
if (i === this.currentYear) {
|
|
240
|
+
year.appendChild(monthsContainer);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
let years = this.selectMonthYear.querySelectorAll('.year');
|
|
244
|
+
let tempSelectedYear = this.selectedYear;
|
|
245
|
+
for (let i = 0; i < years.length; i++) {
|
|
246
|
+
years[i].addEventListener('click', () => {
|
|
247
|
+
let year = parseInt(years[i].innerHTML);
|
|
248
|
+
if (year === tempSelectedYear) {
|
|
249
|
+
return;
|
|
250
|
+
} else {
|
|
251
|
+
tempSelectedYear = year;
|
|
252
|
+
this.selectedYear = year;
|
|
253
|
+
let monthsContainers = this.selectMonthYear.querySelectorAll('.months');
|
|
254
|
+
for (let i = 0; i < monthsContainers.length; i++) {
|
|
255
|
+
monthsContainers[i].remove();
|
|
256
|
+
}
|
|
257
|
+
years[i].appendChild(monthsContainer);
|
|
258
|
+
}
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
private toggleSelectMonthYear() {
|
|
264
|
+
if (this.selectMonthYear.style.display === 'none') {
|
|
265
|
+
this.selectDate.style.display = 'none';
|
|
266
|
+
this.selectMonthYear.style.display = 'block';
|
|
267
|
+
this.header.style.color = '#ccc';
|
|
268
|
+
let years = this.selectMonthYear.querySelectorAll('.year');
|
|
269
|
+
for (let i = 0; i < years.length; i++) {
|
|
270
|
+
if (years[i].querySelector('.months')) {
|
|
271
|
+
years[i].scrollIntoView();
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} else {
|
|
276
|
+
this.hideSelectMonthYear();
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
private hideSelectMonthYear() {
|
|
281
|
+
this.selectDate.style.display = 'block';
|
|
282
|
+
this.selectMonthYear.style.display = 'none';
|
|
283
|
+
this.header.style.color = '#000';
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private showPicker(showpicker: boolean = true) {
|
|
287
|
+
if (showpicker) {
|
|
288
|
+
this.positionPicker();
|
|
289
|
+
this.datepicker.style.display = 'block';
|
|
290
|
+
} else {
|
|
291
|
+
this.datepicker.style.display = 'none';
|
|
292
|
+
this.hideSelectMonthYear();
|
|
293
|
+
return;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
private positionPicker() {
|
|
298
|
+
this.datepicker.style.position = 'fixed';
|
|
299
|
+
|
|
300
|
+
let datepickerHeight = 250;
|
|
301
|
+
if (isMobileDevice()) {
|
|
302
|
+
this.datepicker.style.height = '400px';
|
|
303
|
+
this.datepicker.style.top = '50%';
|
|
304
|
+
this.datepicker.style.left = '50%';
|
|
305
|
+
this.datepicker.style.transform = 'translate(-50%, -50%)';
|
|
306
|
+
this.datepicker.style.width = '90%';
|
|
307
|
+
this.datepicker.style.maxWidth = '300px';
|
|
308
|
+
this.datepicker.style.fontSize = '16px';
|
|
309
|
+
this.datepicker.style.padding = '30px';
|
|
310
|
+
this.header.style.marginBottom = '20px';
|
|
311
|
+
let weekdaysSpans = this.weekdays.querySelectorAll('span');
|
|
312
|
+
let daysSpans = this.days.querySelectorAll('span');
|
|
313
|
+
weekdaysSpans.forEach(span => span.style.marginBottom = '10px');
|
|
314
|
+
daysSpans.forEach(span => span.style.marginBottom = '10px');
|
|
315
|
+
} else {
|
|
316
|
+
this.datepicker.style.height = datepickerHeight + 'px';
|
|
317
|
+
let dateInputRect = this.input.getBoundingClientRect();
|
|
318
|
+
datepickerHeight += 20;
|
|
319
|
+
if (window.innerHeight - dateInputRect.bottom < datepickerHeight) {
|
|
320
|
+
this.datepicker.style.top = 'auto';
|
|
321
|
+
this.datepicker.style.bottom = window.innerHeight - dateInputRect.top + 'px';
|
|
322
|
+
} else {
|
|
323
|
+
this.datepicker.style.bottom = 'auto';
|
|
324
|
+
this.datepicker.style.top = dateInputRect.bottom + 'px';
|
|
325
|
+
}
|
|
326
|
+
this.datepicker.style.left = dateInputRect.left + 'px';
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
private setDateForToday() {
|
|
331
|
+
this.input.value = formatDate(this.selectedDate, this.dateFormat);
|
|
332
|
+
this.showPicker(false);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
private addEventListeners() {
|
|
336
|
+
this.input.addEventListener('click', () => this.showPicker(true));
|
|
337
|
+
this.input.addEventListener('focus', () => this.showPicker(true));
|
|
338
|
+
this.input.addEventListener('change', () => {
|
|
339
|
+
const date = new Date(this.input.value);
|
|
340
|
+
if (date.toString() !== 'Invalid Date') {
|
|
341
|
+
this.selectedDate = date;
|
|
342
|
+
this.selectedMonth = date.getMonth();
|
|
343
|
+
this.selectedYear = date.getFullYear();
|
|
344
|
+
this.selectedDay = date.getDate();
|
|
345
|
+
this.renderCalendar();
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
this.otherTriggers.forEach(trigger => {
|
|
350
|
+
trigger.addEventListener('click', () => this.showPicker(true));
|
|
351
|
+
});
|
|
352
|
+
|
|
353
|
+
document.onclick = (event: Event) => {
|
|
354
|
+
const elementsToNeglect = [this.input, this.datepicker, this.monthYear, this.weekdays, this.days, this.header, this.selectMonthYear];
|
|
355
|
+
const element = event.target as HTMLElement;
|
|
356
|
+
const isNeglected = elementsToNeglect.includes(element) || elementsToNeglect.includes(element.parentElement) || (element).classList.contains('select-month') || element === this.parentElement;
|
|
357
|
+
|
|
358
|
+
if (!isNeglected){
|
|
359
|
+
this.showPicker(false);
|
|
360
|
+
}
|
|
361
|
+
};
|
|
362
|
+
}
|
|
363
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export const CustomDatepickerStyles = `
|
|
2
|
+
.datepicker {
|
|
3
|
+
position: fixed;
|
|
4
|
+
background-color: #fff;
|
|
5
|
+
display: none;
|
|
6
|
+
width: 200px;
|
|
7
|
+
border: 1px solid #ccc;
|
|
8
|
+
border-radius: 5px;
|
|
9
|
+
padding: 10px;
|
|
10
|
+
margin: 0 auto;
|
|
11
|
+
box-shadow: 0 0 10px 0 #ccc;
|
|
12
|
+
font: 12px Arial, sans-serif;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.header {
|
|
16
|
+
display: flex;
|
|
17
|
+
justify-content: space-between;
|
|
18
|
+
align-items: center;
|
|
19
|
+
margin-bottom: 10px;
|
|
20
|
+
}
|
|
21
|
+
.weekdays {
|
|
22
|
+
display: flex;
|
|
23
|
+
justify-content: space-between;
|
|
24
|
+
}
|
|
25
|
+
.weekdays span {
|
|
26
|
+
width: 14.28%;
|
|
27
|
+
text-align: center;
|
|
28
|
+
padding: 5px 0;
|
|
29
|
+
}
|
|
30
|
+
.days {
|
|
31
|
+
display: flex;
|
|
32
|
+
flex-wrap: wrap;
|
|
33
|
+
}
|
|
34
|
+
.days span {
|
|
35
|
+
width: 14.28%;
|
|
36
|
+
text-align: center;
|
|
37
|
+
padding: 5px 0;
|
|
38
|
+
}
|
|
39
|
+
.days span:hover {
|
|
40
|
+
background-color: #B2d5ff;
|
|
41
|
+
cursor: pointer;
|
|
42
|
+
}
|
|
43
|
+
.days span.today {
|
|
44
|
+
border: 1px solid #000;
|
|
45
|
+
}
|
|
46
|
+
.days span.selected-day {
|
|
47
|
+
background-color: #0075ff;
|
|
48
|
+
color: #fff;
|
|
49
|
+
}
|
|
50
|
+
.prev-month, .next-month {
|
|
51
|
+
cursor: pointer;
|
|
52
|
+
}
|
|
53
|
+
.month-year {
|
|
54
|
+
font-weight: bold;
|
|
55
|
+
}
|
|
56
|
+
.month-year:hover {
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
}
|
|
59
|
+
.select-month-year {
|
|
60
|
+
display: none;
|
|
61
|
+
width: 100%;
|
|
62
|
+
overflow-y: auto;
|
|
63
|
+
}
|
|
64
|
+
.select-month-year .year {
|
|
65
|
+
text-align: center;
|
|
66
|
+
background-color: #f0f0f0;
|
|
67
|
+
border-bottom: 1px solid #3f3d3d;
|
|
68
|
+
padding: 5px 0;
|
|
69
|
+
cursor: pointer;
|
|
70
|
+
}
|
|
71
|
+
.select-month-year .year .months {
|
|
72
|
+
display: flex;
|
|
73
|
+
flex-wrap: wrap;
|
|
74
|
+
}
|
|
75
|
+
.select-month-year .year .months span {
|
|
76
|
+
width: 25%;
|
|
77
|
+
text-align: center;
|
|
78
|
+
padding: 10px 0;
|
|
79
|
+
background-color: #fff;
|
|
80
|
+
}
|
|
81
|
+
.select-month-year .year .months span:hover {
|
|
82
|
+
background-color: #B2d5ff;
|
|
83
|
+
cursor: pointer;
|
|
84
|
+
}
|
|
85
|
+
.actions {
|
|
86
|
+
display: flex;
|
|
87
|
+
justify-content: space-between;
|
|
88
|
+
margin-top: 10px;
|
|
89
|
+
}
|
|
90
|
+
.actions input {
|
|
91
|
+
color: #0075ff;
|
|
92
|
+
border: none;
|
|
93
|
+
background-color: transparent;
|
|
94
|
+
padding: 5px;
|
|
95
|
+
border: 1px solid transparent;
|
|
96
|
+
}
|
|
97
|
+
.actions input:hover {
|
|
98
|
+
background-color: #B2d5ff;
|
|
99
|
+
border-color: #000;
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const months: string[] = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
|
|
2
|
+
export const daysOfWeek: string[] = ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'];
|
|
3
|
+
|
|
4
|
+
export const defaultDateFormat = 'yyyy-mm-dd';
|
|
5
|
+
export const supportedDateFormats = [
|
|
6
|
+
'ddmmyyyy',
|
|
7
|
+
'mmddyyyy',
|
|
8
|
+
'dd/mm/yyyy',
|
|
9
|
+
'mm/dd/yyyy',
|
|
10
|
+
'dd-mm-yyyy',
|
|
11
|
+
'mm-dd-yyyy',
|
|
12
|
+
'yyyy-mm-dd',
|
|
13
|
+
'yyyy-dd-mm',
|
|
14
|
+
'Month dd, yyyy',
|
|
15
|
+
'mm/dd/yy',
|
|
16
|
+
'dd/mm/yy',
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
export function formatDate(date: Date, dateFormat: string): string {
|
|
20
|
+
const year = date.getFullYear();
|
|
21
|
+
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
22
|
+
const day = date.getDate().toString().padStart(2, '0');
|
|
23
|
+
const monthName = date.toLocaleString('default', { month: 'long' });
|
|
24
|
+
|
|
25
|
+
const dateFormats = {
|
|
26
|
+
'ddmmyyyy': `${day}${month}${year}`,
|
|
27
|
+
'mmddyyyy': `${month}${day}${year}`,
|
|
28
|
+
'dd/mm/yyyy': `${day}/${month}/${year}`,
|
|
29
|
+
'mm/dd/yyyy': `${month}/${day}/${year}`,
|
|
30
|
+
'dd-mm-yyyy': `${day}-${month}-${year}`,
|
|
31
|
+
'mm-dd-yyyy': `${month}-${day}-${year}`,
|
|
32
|
+
'yyyy-mm-dd': `${year}-${month}-${day}`,
|
|
33
|
+
'yyyy-dd-mm': `${year}-${day}-${month}`,
|
|
34
|
+
'Month dd, yyyy': `${monthName} ${day}, ${year}`,
|
|
35
|
+
'mm/dd/yy': `${month}/${day}/${year.toString().slice(-2)}`,
|
|
36
|
+
'dd/mm/yy': `${day}/${month}/${year.toString().slice(-2)}`,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return dateFormats[dateFormat];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isMobileDevice() {
|
|
43
|
+
return /Android|webOS|iPhone|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || window.innerWidth < 480;
|
|
44
|
+
}
|