@materializecss/materialize 2.0.3-beta → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +16 -18
  3. package/dist/css/materialize.css +73 -26
  4. package/dist/css/materialize.min.css +3 -3
  5. package/dist/js/materialize.js +560 -2015
  6. package/dist/js/materialize.min.js +3 -3
  7. package/dist/js/materialize.min.js.map +1 -1
  8. package/dist/src/buttons.d.ts.map +1 -1
  9. package/dist/src/cards.d.ts.map +1 -1
  10. package/dist/src/collapsible.d.ts +1 -0
  11. package/dist/src/collapsible.d.ts.map +1 -1
  12. package/dist/src/dropdown.d.ts +1 -0
  13. package/dist/src/dropdown.d.ts.map +1 -1
  14. package/dist/src/global.d.ts.map +1 -1
  15. package/dist/src/materialbox.d.ts +14 -10
  16. package/dist/src/materialbox.d.ts.map +1 -1
  17. package/dist/src/modal.d.ts.map +1 -1
  18. package/dist/src/range.d.ts.map +1 -1
  19. package/dist/src/scrollspy.d.ts.map +1 -1
  20. package/dist/src/sidenav.d.ts +25 -25
  21. package/dist/src/sidenav.d.ts.map +1 -1
  22. package/dist/src/slider.d.ts +12 -12
  23. package/dist/src/slider.d.ts.map +1 -1
  24. package/dist/src/tabs.d.ts +1 -1
  25. package/dist/src/tabs.d.ts.map +1 -1
  26. package/dist/src/toasts.d.ts +7 -2
  27. package/dist/src/toasts.d.ts.map +1 -1
  28. package/dist/src/tooltip.d.ts.map +1 -1
  29. package/package.json +29 -44
  30. package/sass/components/_collapsible.scss +14 -2
  31. package/sass/components/_materialbox.scss +2 -2
  32. package/sass/components/_modal.scss +0 -1
  33. package/sass/components/_tooltip.scss +18 -8
  34. package/sass/components/_variables.scss +2 -2
  35. package/Gruntfile.js +0 -385
  36. package/src/autocomplete.ts +0 -553
  37. package/src/bounding.ts +0 -6
  38. package/src/buttons.ts +0 -260
  39. package/src/cards.ts +0 -53
  40. package/src/carousel.ts +0 -676
  41. package/src/characterCounter.ts +0 -117
  42. package/src/chips.ts +0 -439
  43. package/src/collapsible.ts +0 -249
  44. package/src/component.ts +0 -120
  45. package/src/datepicker.ts +0 -1076
  46. package/src/dropdown.ts +0 -644
  47. package/src/edges.ts +0 -6
  48. package/src/forms.ts +0 -132
  49. package/src/global.ts +0 -114
  50. package/src/index.ts +0 -26
  51. package/src/materialbox.ts +0 -404
  52. package/src/modal.ts +0 -341
  53. package/src/parallax.ts +0 -149
  54. package/src/pushpin.ts +0 -165
  55. package/src/range.ts +0 -198
  56. package/src/scrollspy.ts +0 -263
  57. package/src/select.ts +0 -484
  58. package/src/sidenav.ts +0 -543
  59. package/src/slider.ts +0 -474
  60. package/src/tabs.ts +0 -347
  61. package/src/tapTarget.ts +0 -273
  62. package/src/timepicker.ts +0 -832
  63. package/src/toasts.ts +0 -290
  64. package/src/tooltip.ts +0 -366
  65. package/src/utils.ts +0 -271
  66. package/src/waves.ts +0 -70
package/src/datepicker.ts DELETED
@@ -1,1076 +0,0 @@
1
- import { Modal } from "./modal";
2
- import { Utils } from "./utils";
3
- import { FormSelect } from "./select";
4
- import { BaseOptions, Component, InitElements, MElement, I18nOptions } from "./component";
5
-
6
- export interface DateI18nOptions extends I18nOptions {
7
- previousMonth: string;
8
- nextMonth: string;
9
- months: string[];
10
- monthsShort: string[];
11
- weekdays: string[];
12
- weekdaysShort: string[];
13
- weekdaysAbbrev: string[];
14
- };
15
-
16
- export interface DatepickerOptions extends BaseOptions {
17
- /**
18
- * Automatically close picker when date is selected.
19
- * @default false
20
- */
21
- autoClose: boolean;
22
- /**
23
- * The date output format for the input field value
24
- * or a function taking the date and outputting the
25
- * formatted date string.
26
- * @default 'mmm dd, yyyy'
27
- */
28
- format: string | ((d: Date) => string);
29
- /**
30
- * Used to create date object from current input string.
31
- * @default null
32
- */
33
- parse: ((value: string, format: string) => Date) | null;
34
- /**
35
- * The initial date to view when first opened.
36
- * @default null
37
- */
38
- defaultDate: Date | null;
39
- /**
40
- * Make the `defaultDate` the initial selected value.
41
- * @default false
42
- */
43
- setDefaultDate: boolean;
44
- /**
45
- * Prevent selection of any date on the weekend.
46
- * @default false
47
- */
48
- disableWeekends: boolean;
49
- /**
50
- * Custom function to disable certain days.
51
- * @default null
52
- */
53
- disableDayFn: ((day: Date) => boolean) | null;
54
- /**
55
- * First day of week (0: Sunday, 1: Monday etc).
56
- * @default 0
57
- */
58
- firstDay: number;
59
- /**
60
- * The earliest date that can be selected.
61
- * @default null
62
- */
63
- minDate: Date | null;
64
- /**
65
- * The latest date that can be selected.
66
- * @default null
67
- */
68
- maxDate: Date | null;
69
- /**
70
- * Number of years either side, or array of upper/lower range.
71
- * @default 10
72
- */
73
- yearRange: number | number[];
74
- /**
75
- * Sort year range in reverse order.
76
- * @default false
77
- */
78
- yearRangeReverse: boolean;
79
- /**
80
- * Changes Datepicker to RTL.
81
- * @default false
82
- */
83
- isRTL: boolean;
84
- /**
85
- * Show month after year in Datepicker title.
86
- * @default false
87
- */
88
- showMonthAfterYear: boolean;
89
- /**
90
- * Render days of the calendar grid that fall in the next
91
- * or previous month.
92
- * @default false
93
- */
94
- showDaysInNextAndPreviousMonths: boolean;
95
- /**
96
- * Specify a DOM element OR selector for a DOM element to render
97
- * the calendar in, by default it will be placed before the input.
98
- * @default null
99
- */
100
- container: HTMLElement | string | null;
101
- /**
102
- * Show the clear button in the datepicker.
103
- * @default false
104
- */
105
- showClearBtn: boolean;
106
- /**
107
- * Internationalization options.
108
- */
109
- i18n: Partial<DateI18nOptions>;
110
- /**
111
- * An array of string returned by `Date.toDateString()`,
112
- * indicating there are events in the specified days.
113
- * @default []
114
- */
115
- events: string[];
116
- /**
117
- * Callback function when date is selected,
118
- * first parameter is the newly selected date.
119
- * @default null
120
- */
121
- onSelect: ((selectedDate: Date) => void) | null;
122
- /**
123
- * Callback function when Datepicker is opened.
124
- * @default null
125
- */
126
- onOpen: (() => void) | null;
127
- /**
128
- * Callback function when Datepicker is closed.
129
- * @default null
130
- */
131
- onClose: (() => void) | null;
132
- /**
133
- * Callback function when Datepicker HTML is refreshed.
134
- * @default null
135
- */
136
- onDraw: (() => void) | null;
137
-
138
- /** Field used for internal calculations DO NOT CHANGE IT */
139
- minYear?: any;
140
- /** Field used for internal calculations DO NOT CHANGE IT */
141
- maxYear?: any;
142
- /** Field used for internal calculations DO NOT CHANGE IT */
143
- minMonth?: any;
144
- /** Field used for internal calculations DO NOT CHANGE IT */
145
- maxMonth?: any;
146
- /** Field used for internal calculations DO NOT CHANGE IT */
147
- startRange?: any;
148
- /** Field used for internal calculations DO NOT CHANGE IT */
149
- endRange?: any;
150
- }
151
-
152
- let _defaults: DatepickerOptions = {
153
- // Close when date is selected
154
- autoClose: false,
155
- // the default output format for the input field value
156
- format: 'mmm dd, yyyy',
157
- // Used to create date object from current input string
158
- parse: null,
159
- // The initial date to view when first opened
160
- defaultDate: null,
161
- // Make the `defaultDate` the initial selected value
162
- setDefaultDate: false,
163
- disableWeekends: false,
164
- disableDayFn: null,
165
- // First day of week (0: Sunday, 1: Monday etc)
166
- firstDay: 0,
167
- // The earliest date that can be selected
168
- minDate: null,
169
- // Thelatest date that can be selected
170
- maxDate: null,
171
- // Number of years either side, or array of upper/lower range
172
- yearRange: 10,
173
- // used internally (don't config outside)
174
- minYear: 0,
175
- maxYear: 9999,
176
- minMonth: undefined,
177
- maxMonth: undefined,
178
- startRange: null,
179
- endRange: null,
180
- isRTL: false,
181
- yearRangeReverse: false,
182
- // Render the month after year in the calendar title
183
- showMonthAfterYear: false,
184
- // Render days of the calendar grid that fall in the next or previous month
185
- showDaysInNextAndPreviousMonths: false,
186
- // Specify a DOM element to render the calendar in
187
- container: null,
188
- // Show clear button
189
- showClearBtn: false,
190
- // internationalization
191
- i18n: {
192
- cancel: 'Cancel',
193
- clear: 'Clear',
194
- done: 'Ok',
195
- previousMonth: '‹',
196
- nextMonth: '›',
197
- months: [
198
- 'January',
199
- 'February',
200
- 'March',
201
- 'April',
202
- 'May',
203
- 'June',
204
- 'July',
205
- 'August',
206
- 'September',
207
- 'October',
208
- 'November',
209
- 'December'
210
- ],
211
- monthsShort: [
212
- 'Jan',
213
- 'Feb',
214
- 'Mar',
215
- 'Apr',
216
- 'May',
217
- 'Jun',
218
- 'Jul',
219
- 'Aug',
220
- 'Sep',
221
- 'Oct',
222
- 'Nov',
223
- 'Dec'
224
- ],
225
- weekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
226
- weekdaysShort: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
227
- weekdaysAbbrev: ['S', 'M', 'T', 'W', 'T', 'F', 'S']
228
- },
229
- // events array
230
- events: [],
231
- // callback function
232
- onSelect: null,
233
- onOpen: null,
234
- onClose: null,
235
- onDraw: null
236
- };
237
-
238
- export class Datepicker extends Component<DatepickerOptions> {
239
- declare el: HTMLInputElement
240
- id: string;
241
- /** If the picker is open. */
242
- isOpen: boolean;
243
- modal: Modal;
244
- calendarEl: HTMLElement;
245
- /** CLEAR button instance. */
246
- clearBtn: HTMLElement;
247
- /** DONE button instance */
248
- doneBtn: HTMLElement;
249
- cancelBtn: HTMLElement;
250
- modalEl: HTMLElement;
251
- yearTextEl: HTMLElement;
252
- dateTextEl: HTMLElement;
253
- /** The selected Date. */
254
- date: Date;
255
- formats: any;
256
- calendars: any;
257
- private _y: any;
258
- private _m: any;
259
- static _template: string;
260
-
261
- constructor(el: HTMLInputElement, options: Partial<DatepickerOptions>) {
262
- super(el, options, Datepicker);
263
- (this.el as any).M_Datepicker = this;
264
-
265
- this.options = {
266
- ...Datepicker.defaults,
267
- ...options
268
- };
269
-
270
- // make sure i18n defaults are not lost when only few i18n option properties are passed
271
- if (!!options && options.hasOwnProperty('i18n') && typeof options.i18n === 'object') {
272
- this.options.i18n = {...Datepicker.defaults.i18n, ...options.i18n};
273
- }
274
-
275
- // Remove time component from minDate and maxDate options
276
- if (this.options.minDate) this.options.minDate.setHours(0, 0, 0, 0);
277
- if (this.options.maxDate) this.options.maxDate.setHours(0, 0, 0, 0);
278
-
279
- this.id = Utils.guid();
280
-
281
- this._setupVariables();
282
- this._insertHTMLIntoDOM();
283
- this._setupModal();
284
- this._setupEventHandlers();
285
-
286
- if (!this.options.defaultDate) {
287
- this.options.defaultDate = new Date(Date.parse(this.el.value));
288
- }
289
-
290
- let defDate = this.options.defaultDate;
291
- if (Datepicker._isDate(defDate)) {
292
- if (this.options.setDefaultDate) {
293
- this.setDate(defDate, true);
294
- this.setInputValue();
295
- }
296
- else {
297
- this.gotoDate(defDate);
298
- }
299
- }
300
- else {
301
- this.gotoDate(new Date());
302
- }
303
- this.isOpen = false;
304
- }
305
-
306
- static get defaults() {
307
- return _defaults;
308
- }
309
-
310
- /**
311
- * Initializes instance of Datepicker.
312
- * @param el HTML element.
313
- * @param options Component options.
314
- */
315
- static init(el: HTMLInputElement, options?: Partial<DatepickerOptions>): Datepicker;
316
- /**
317
- * Initializes instances of Datepicker.
318
- * @param els HTML elements.
319
- * @param options Component options.
320
- */
321
- static init(els: InitElements<HTMLInputElement | MElement>, options?: Partial<DatepickerOptions>): Datepicker[];
322
- /**
323
- * Initializes instances of Datepicker.
324
- * @param els HTML elements.
325
- * @param options Component options.
326
- */
327
- static init(els: HTMLInputElement | InitElements<HTMLInputElement | MElement>, options: Partial<DatepickerOptions> = {}): Datepicker | Datepicker[] {
328
- return super.init(els, options, Datepicker);
329
- }
330
-
331
- static _isDate(obj) {
332
- return /Date/.test(Object.prototype.toString.call(obj)) && !isNaN(obj.getTime());
333
- }
334
-
335
- static _isWeekend(date) {
336
- let day = date.getDay();
337
- return day === 0 || day === 6;
338
- }
339
-
340
- static _setToStartOfDay(date) {
341
- if (Datepicker._isDate(date)) date.setHours(0, 0, 0, 0);
342
- }
343
-
344
- static _getDaysInMonth(year, month) {
345
- return [31, Datepicker._isLeapYear(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][
346
- month
347
- ];
348
- }
349
-
350
- static _isLeapYear(year) {
351
- // solution by Matti Virkkunen: http://stackoverflow.com/a/4881951
352
- return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
353
- }
354
-
355
- static _compareDates(a, b) {
356
- // weak date comparison (use setToStartOfDay(date) to ensure correct result)
357
- return a.getTime() === b.getTime();
358
- }
359
-
360
- static getInstance(el: HTMLElement): Datepicker {
361
- return (el as any).M_Datepicker;
362
- }
363
-
364
- destroy() {
365
- this._removeEventHandlers();
366
- this.modal.destroy();
367
- this.modalEl.remove();
368
- this.destroySelects();
369
- (this.el as any).M_Datepicker = undefined;
370
- }
371
-
372
- destroySelects() {
373
- let oldYearSelect = this.calendarEl.querySelector('.orig-select-year');
374
- if (oldYearSelect) {
375
- FormSelect.getInstance(oldYearSelect as HTMLElement).destroy();
376
- }
377
- let oldMonthSelect = this.calendarEl.querySelector('.orig-select-month');
378
- if (oldMonthSelect) {
379
- FormSelect.getInstance(oldMonthSelect as HTMLElement).destroy();
380
- }
381
- }
382
-
383
- _insertHTMLIntoDOM() {
384
- if (this.options.showClearBtn) {
385
- this.clearBtn.style.visibility = '';
386
- this.clearBtn.innerText = this.options.i18n.clear;
387
- }
388
- this.doneBtn.innerText = this.options.i18n.done;
389
- this.cancelBtn.innerText = this.options.i18n.cancel;
390
-
391
- if (this.options.container) {
392
- const optEl = this.options.container;
393
- this.options.container =
394
- optEl instanceof HTMLElement ? optEl : document.querySelector(optEl) as HTMLElement;
395
- this.options.container.append(this.modalEl);
396
- }
397
- else {
398
- //this.modalEl.before(this.el);
399
- this.el.parentElement.appendChild(this.modalEl);
400
- }
401
- }
402
-
403
- _setupModal() {
404
- this.modalEl.id = 'modal-' + this.id;
405
- this.modal = Modal.init(this.modalEl, {
406
- onCloseEnd: () => {
407
- this.isOpen = false;
408
- }
409
- });
410
- }
411
-
412
- /**
413
- * Gets a string representation of the selected date.
414
- */
415
- toString(format: string | ((d: Date) => string) = null): string {
416
- format = format || this.options.format;
417
- if (typeof format === 'function') return format(this.date);
418
- if (!Datepicker._isDate(this.date)) return '';
419
- // String Format
420
- const formatArray = format.split(/(d{1,4}|m{1,4}|y{4}|yy|!.)/g);
421
- const formattedDate = formatArray
422
- .map(label => this.formats[label] ? this.formats[label]() : label)
423
- .join('');
424
- return formattedDate;
425
- }
426
-
427
- /**
428
- * Set a date on the datepicker.
429
- * @param date Date to set on the datepicker.
430
- * @param preventOnSelect Undocumented as of 5 March 2018.
431
- */
432
- setDate(date: Date | string = null, preventOnSelect: boolean = false) {
433
- if (!date) {
434
- this.date = null;
435
- this._renderDateDisplay();
436
- return this.draw();
437
- }
438
- if (typeof date === 'string') {
439
- date = new Date(Date.parse(date));
440
- }
441
- if (!Datepicker._isDate(date)) {
442
- return;
443
- }
444
- let min = this.options.minDate,
445
- max = this.options.maxDate;
446
- if (Datepicker._isDate(min) && date < min) {
447
- date = min;
448
- }
449
- else if (Datepicker._isDate(max) && date > max) {
450
- date = max;
451
- }
452
- this.date = new Date(date.getTime());
453
- this._renderDateDisplay();
454
- Datepicker._setToStartOfDay(this.date);
455
- this.gotoDate(this.date);
456
- if (!preventOnSelect && typeof this.options.onSelect === 'function') {
457
- this.options.onSelect.call(this, this.date);
458
- }
459
- }
460
-
461
- /**
462
- * Sets current date as the input value.
463
- */
464
- setInputValue() {
465
- this.el.value = this.toString();
466
- this.el.dispatchEvent(new CustomEvent('change', {bubbles:true, cancelable:true, composed:true, detail: {firedBy: this}}));
467
- }
468
-
469
- _renderDateDisplay() {
470
- let displayDate = Datepicker._isDate(this.date) ? this.date : new Date();
471
- let i18n = this.options.i18n;
472
- let day = i18n.weekdaysShort[displayDate.getDay()];
473
- let month = i18n.monthsShort[displayDate.getMonth()];
474
- let date = displayDate.getDate();
475
- this.yearTextEl.innerHTML = displayDate.getFullYear().toString();
476
- this.dateTextEl.innerHTML = `${day}, ${month} ${date}`;
477
- }
478
-
479
- /**
480
- * Change date view to a specific date on the datepicker.
481
- * @param date Date to show on the datepicker.
482
- */
483
- gotoDate(date: Date) {
484
- let newCalendar = true;
485
- if (!Datepicker._isDate(date)) {
486
- return;
487
- }
488
- if (this.calendars) {
489
- let firstVisibleDate = new Date(this.calendars[0].year, this.calendars[0].month, 1),
490
- lastVisibleDate = new Date(
491
- this.calendars[this.calendars.length - 1].year,
492
- this.calendars[this.calendars.length - 1].month,
493
- 1
494
- ),
495
- visibleDate = date.getTime();
496
- // get the end of the month
497
- lastVisibleDate.setMonth(lastVisibleDate.getMonth() + 1);
498
- lastVisibleDate.setDate(lastVisibleDate.getDate() - 1);
499
- newCalendar =
500
- visibleDate < firstVisibleDate.getTime() || lastVisibleDate.getTime() < visibleDate;
501
- }
502
- if (newCalendar) {
503
- this.calendars = [
504
- {
505
- month: date.getMonth(),
506
- year: date.getFullYear()
507
- }
508
- ];
509
- }
510
- this.adjustCalendars();
511
- }
512
-
513
- adjustCalendars() {
514
- this.calendars[0] = this.adjustCalendar(this.calendars[0]);
515
- this.draw();
516
- }
517
-
518
- adjustCalendar(calendar) {
519
- if (calendar.month < 0) {
520
- calendar.year -= Math.ceil(Math.abs(calendar.month) / 12);
521
- calendar.month += 12;
522
- }
523
- if (calendar.month > 11) {
524
- calendar.year += Math.floor(Math.abs(calendar.month) / 12);
525
- calendar.month -= 12;
526
- }
527
- return calendar;
528
- }
529
-
530
- nextMonth() {
531
- this.calendars[0].month++;
532
- this.adjustCalendars();
533
- }
534
-
535
- prevMonth() {
536
- this.calendars[0].month--;
537
- this.adjustCalendars();
538
- }
539
-
540
- render(year, month, randId) {
541
- let opts = this.options,
542
- now = new Date(),
543
- days = Datepicker._getDaysInMonth(year, month),
544
- before = new Date(year, month, 1).getDay(),
545
- data = [],
546
- row = [];
547
- Datepicker._setToStartOfDay(now);
548
- if (opts.firstDay > 0) {
549
- before -= opts.firstDay;
550
- if (before < 0) {
551
- before += 7;
552
- }
553
- }
554
- let previousMonth = month === 0 ? 11 : month - 1,
555
- nextMonth = month === 11 ? 0 : month + 1,
556
- yearOfPreviousMonth = month === 0 ? year - 1 : year,
557
- yearOfNextMonth = month === 11 ? year + 1 : year,
558
- daysInPreviousMonth = Datepicker._getDaysInMonth(yearOfPreviousMonth, previousMonth);
559
- let cells = days + before,
560
- after = cells;
561
- while (after > 7) {
562
- after -= 7;
563
- }
564
- cells += 7 - after;
565
- let isWeekSelected = false;
566
- for (let i = 0, r = 0; i < cells; i++) {
567
- let day = new Date(year, month, 1 + (i - before)),
568
- isSelected = Datepicker._isDate(this.date)
569
- ? Datepicker._compareDates(day, this.date)
570
- : false,
571
- isToday = Datepicker._compareDates(day, now),
572
- hasEvent = opts.events.indexOf(day.toDateString()) !== -1 ? true : false,
573
- isEmpty = i < before || i >= days + before,
574
- dayNumber = 1 + (i - before),
575
- monthNumber = month,
576
- yearNumber = year,
577
- isStartRange = opts.startRange && Datepicker._compareDates(opts.startRange, day),
578
- isEndRange = opts.endRange && Datepicker._compareDates(opts.endRange, day),
579
- isInRange =
580
- opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange,
581
- isDisabled =
582
- (opts.minDate && day < opts.minDate) ||
583
- (opts.maxDate && day > opts.maxDate) ||
584
- (opts.disableWeekends && Datepicker._isWeekend(day)) ||
585
- (opts.disableDayFn && opts.disableDayFn(day));
586
-
587
- if (isEmpty) {
588
- if (i < before) {
589
- dayNumber = daysInPreviousMonth + dayNumber;
590
- monthNumber = previousMonth;
591
- yearNumber = yearOfPreviousMonth;
592
- } else {
593
- dayNumber = dayNumber - days;
594
- monthNumber = nextMonth;
595
- yearNumber = yearOfNextMonth;
596
- }
597
- }
598
-
599
- let dayConfig = {
600
- day: dayNumber,
601
- month: monthNumber,
602
- year: yearNumber,
603
- hasEvent: hasEvent,
604
- isSelected: isSelected,
605
- isToday: isToday,
606
- isDisabled: isDisabled,
607
- isEmpty: isEmpty,
608
- isStartRange: isStartRange,
609
- isEndRange: isEndRange,
610
- isInRange: isInRange,
611
- showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths
612
- };
613
-
614
- row.push(this.renderDay(dayConfig));
615
-
616
- if (++r === 7) {
617
- data.push(this.renderRow(row, opts.isRTL, isWeekSelected));
618
- row = [];
619
- r = 0;
620
- isWeekSelected = false;
621
- }
622
- }
623
- return this.renderTable(opts, data, randId);
624
- }
625
-
626
- renderDay(opts) {
627
- let arr = [];
628
- let ariaSelected = 'false';
629
- if (opts.isEmpty) {
630
- if (opts.showDaysInNextAndPreviousMonths) {
631
- arr.push('is-outside-current-month');
632
- arr.push('is-selection-disabled');
633
- } else {
634
- return '<td class="is-empty"></td>';
635
- }
636
- }
637
- if (opts.isDisabled) {
638
- arr.push('is-disabled');
639
- }
640
-
641
- if (opts.isToday) {
642
- arr.push('is-today');
643
- }
644
- if (opts.isSelected) {
645
- arr.push('is-selected');
646
- ariaSelected = 'true';
647
- }
648
- if (opts.hasEvent) {
649
- arr.push('has-event');
650
- }
651
- if (opts.isInRange) {
652
- arr.push('is-inrange');
653
- }
654
- if (opts.isStartRange) {
655
- arr.push('is-startrange');
656
- }
657
- if (opts.isEndRange) {
658
- arr.push('is-endrange');
659
- }
660
- return (
661
- `<td data-day="${opts.day}" class="${arr.join(' ')}" aria-selected="${ariaSelected}">` +
662
- `<button class="datepicker-day-button" type="button" data-year="${opts.year}" data-month="${opts.month}" data-day="${opts.day}">${opts.day}</button>` +
663
- '</td>'
664
- );
665
- }
666
-
667
- renderRow(days, isRTL, isRowSelected) {
668
- return (
669
- '<tr class="datepicker-row' +
670
- (isRowSelected ? ' is-selected' : '') +
671
- '">' +
672
- (isRTL ? days.reverse() : days).join('') +
673
- '</tr>'
674
- );
675
- }
676
-
677
- renderTable(opts, data, randId) {
678
- return (
679
- '<div class="datepicker-table-wrapper"><table cellpadding="0" cellspacing="0" class="datepicker-table" role="grid" aria-labelledby="' +
680
- randId +
681
- '">' +
682
- this.renderHead(opts) +
683
- this.renderBody(data) +
684
- '</table></div>'
685
- );
686
- }
687
-
688
- renderHead(opts) {
689
- let i,
690
- arr = [];
691
- for (i = 0; i < 7; i++) {
692
- arr.push(
693
- `<th scope="col"><abbr title="${this.renderDayName(opts, i)}">${this.renderDayName(
694
- opts,
695
- i,
696
- true
697
- )}</abbr></th>`
698
- );
699
- }
700
- return '<thead><tr>' + (opts.isRTL ? arr.reverse() : arr).join('') + '</tr></thead>';
701
- }
702
-
703
- renderBody(rows) {
704
- return '<tbody>' + rows.join('') + '</tbody>';
705
- }
706
-
707
- renderTitle(instance, c, year, month, refYear, randId) {
708
- let i,
709
- j,
710
- arr,
711
- opts = this.options,
712
- isMinYear = year === opts.minYear,
713
- isMaxYear = year === opts.maxYear,
714
- html =
715
- '<div id="' +
716
- randId +
717
- '" class="datepicker-controls" role="heading" aria-live="assertive">',
718
- monthHtml,
719
- yearHtml,
720
- prev = true,
721
- next = true;
722
-
723
- for (arr = [], i = 0; i < 12; i++) {
724
- arr.push(
725
- '<option value="' +
726
- (year === refYear ? i - c : 12 + i - c) +
727
- '"' +
728
- (i === month ? ' selected="selected"' : '') +
729
- ((isMinYear && i < opts.minMonth) || (isMaxYear && i > opts.maxMonth)
730
- ? 'disabled="disabled"'
731
- : '') +
732
- '>' +
733
- opts.i18n.months[i] +
734
- '</option>'
735
- );
736
- }
737
-
738
- monthHtml = '<select class="datepicker-select orig-select-month" tabindex="-1">'+arr.join('')+'</select>';
739
-
740
- if (Array.isArray(opts.yearRange)) {
741
- i = opts.yearRange[0];
742
- j = opts.yearRange[1] + 1;
743
- }
744
- else {
745
- i = year - opts.yearRange;
746
- j = 1 + year + opts.yearRange;
747
- }
748
-
749
- for (arr = []; i < j && i <= opts.maxYear; i++) {
750
- if (i >= opts.minYear) {
751
- arr.push(`<option value="${i}" ${i === year ? 'selected="selected"' : ''}>${i}</option>`);
752
- }
753
- }
754
- if (opts.yearRangeReverse) arr.reverse();
755
-
756
- yearHtml = `<select class="datepicker-select orig-select-year" tabindex="-1">${arr.join('')}</select>`;
757
-
758
- let leftArrow =
759
- '<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z"/><path d="M0-.5h24v24H0z" fill="none"/></svg>';
760
- html += `<button class="month-prev${
761
- prev ? '' : ' is-disabled'
762
- } btn-flat" type="button">${leftArrow}</button>`;
763
-
764
- html += '<div class="selects-container">';
765
- if (opts.showMonthAfterYear) {
766
- html += yearHtml + monthHtml;
767
- } else {
768
- html += monthHtml + yearHtml;
769
- }
770
- html += '</div>';
771
-
772
- if (isMinYear && (month === 0 || opts.minMonth >= month)) {
773
- prev = false;
774
- }
775
-
776
- if (isMaxYear && (month === 11 || opts.maxMonth <= month)) {
777
- next = false;
778
- }
779
-
780
- let rightArrow =
781
- '<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg"><path d="M8.59 16.34l4.58-4.59-4.58-4.59L10 5.75l6 6-6 6z"/><path d="M0-.25h24v24H0z" fill="none"/></svg>';
782
- html += `<button class="month-next${
783
- next ? '' : ' is-disabled'
784
- } btn-flat" type="button">${rightArrow}</button>`;
785
-
786
- return (html += '</div>');
787
- }
788
-
789
- // refresh HTML
790
- draw(force: boolean = false) {
791
- if (!this.isOpen && !force) return;
792
- let opts = this.options,
793
- minYear = opts.minYear,
794
- maxYear = opts.maxYear,
795
- minMonth = opts.minMonth,
796
- maxMonth = opts.maxMonth,
797
- html = '',
798
- randId;
799
-
800
- if (this._y <= minYear) {
801
- this._y = minYear;
802
- if (!isNaN(minMonth) && this._m < minMonth) {
803
- this._m = minMonth;
804
- }
805
- }
806
- if (this._y >= maxYear) {
807
- this._y = maxYear;
808
- if (!isNaN(maxMonth) && this._m > maxMonth) {
809
- this._m = maxMonth;
810
- }
811
- }
812
-
813
- randId =
814
- 'datepicker-title-' +
815
- Math.random()
816
- .toString(36)
817
- .replace(/[^a-z]+/g, '')
818
- .substr(0, 2);
819
-
820
- for (let c = 0; c < 1; c++) {
821
- this._renderDateDisplay();
822
- html +=
823
- this.renderTitle(
824
- this,
825
- c,
826
- this.calendars[c].year,
827
- this.calendars[c].month,
828
- this.calendars[0].year,
829
- randId
830
- ) + this.render(this.calendars[c].year, this.calendars[c].month, randId);
831
- }
832
-
833
- this.destroySelects();
834
-
835
- this.calendarEl.innerHTML = html;
836
-
837
- // Init Materialize Select
838
- let yearSelect = this.calendarEl.querySelector('.orig-select-year') as HTMLSelectElement;
839
- let monthSelect = this.calendarEl.querySelector('.orig-select-month') as HTMLSelectElement;
840
- FormSelect.init(yearSelect, {
841
- classes: 'select-year',
842
- dropdownOptions: { container: document.body, constrainWidth: false }
843
- });
844
- FormSelect.init(monthSelect, {
845
- classes: 'select-month',
846
- dropdownOptions: { container: document.body, constrainWidth: false }
847
- });
848
-
849
- // Add change handlers for select
850
- yearSelect.addEventListener('change', this._handleYearChange);
851
- monthSelect.addEventListener('change', this._handleMonthChange);
852
-
853
- if (typeof this.options.onDraw === 'function') {
854
- this.options.onDraw.call(this);
855
- }
856
- }
857
-
858
- _setupEventHandlers() {
859
- this.el.addEventListener('click', this._handleInputClick);
860
- this.el.addEventListener('keydown', this._handleInputKeydown);
861
- this.el.addEventListener('change', this._handleInputChange);
862
- this.calendarEl.addEventListener('click', this._handleCalendarClick);
863
- this.doneBtn.addEventListener('click', this._finishSelection);
864
- this.cancelBtn.addEventListener('click', this.close);
865
-
866
- if (this.options.showClearBtn) {
867
- this.clearBtn.addEventListener('click', this._handleClearClick);
868
- }
869
- }
870
-
871
- _setupVariables() {
872
- const template = document.createElement('template');
873
- template.innerHTML = Datepicker._template.trim();
874
- this.modalEl = <HTMLElement>template.content.firstChild;
875
-
876
- this.calendarEl = this.modalEl.querySelector('.datepicker-calendar');
877
- this.yearTextEl = this.modalEl.querySelector('.year-text');
878
- this.dateTextEl = this.modalEl.querySelector('.date-text');
879
- if (this.options.showClearBtn) {
880
- this.clearBtn = this.modalEl.querySelector('.datepicker-clear');
881
- }
882
- this.doneBtn = this.modalEl.querySelector('.datepicker-done');
883
- this.cancelBtn = this.modalEl.querySelector('.datepicker-cancel');
884
-
885
- this.formats = {
886
- d: () => {
887
- return this.date.getDate();
888
- },
889
- dd: () => {
890
- let d = this.date.getDate();
891
- return (d < 10 ? '0' : '') + d;
892
- },
893
- ddd: () => {
894
- return this.options.i18n.weekdaysShort[this.date.getDay()];
895
- },
896
- dddd: () => {
897
- return this.options.i18n.weekdays[this.date.getDay()];
898
- },
899
- m: () => {
900
- return this.date.getMonth() + 1;
901
- },
902
- mm: () => {
903
- let m = this.date.getMonth() + 1;
904
- return (m < 10 ? '0' : '') + m;
905
- },
906
- mmm: () => {
907
- return this.options.i18n.monthsShort[this.date.getMonth()];
908
- },
909
- mmmm: () => {
910
- return this.options.i18n.months[this.date.getMonth()];
911
- },
912
- yy: () => {
913
- return ('' + this.date.getFullYear()).slice(2);
914
- },
915
- yyyy: () => {
916
- return this.date.getFullYear();
917
- }
918
- };
919
- }
920
-
921
- _removeEventHandlers() {
922
- this.el.removeEventListener('click', this._handleInputClick);
923
- this.el.removeEventListener('keydown', this._handleInputKeydown);
924
- this.el.removeEventListener('change', this._handleInputChange);
925
- this.calendarEl.removeEventListener('click', this._handleCalendarClick);
926
- }
927
-
928
- _handleInputClick = () => {
929
- this.open();
930
- }
931
-
932
- _handleInputKeydown = (e: KeyboardEvent) => {
933
- if (Utils.keys.ENTER.includes(e.key)) {
934
- e.preventDefault();
935
- this.open();
936
- }
937
- }
938
-
939
- _handleCalendarClick = (e) => {
940
- if (!this.isOpen) return;
941
- const target = <HTMLElement>(e.target);
942
- if (!target.classList.contains('is-disabled')) {
943
- if (
944
- target.classList.contains('datepicker-day-button') &&
945
- !target.classList.contains('is-empty') &&
946
- !target.parentElement.classList.contains('is-disabled')
947
- ) {
948
- this.setDate(
949
- new Date(
950
- e.target.getAttribute('data-year'),
951
- e.target.getAttribute('data-month'),
952
- e.target.getAttribute('data-day')
953
- )
954
- );
955
- if (this.options.autoClose) {
956
- this._finishSelection();
957
- }
958
- }
959
- else if (target.closest('.month-prev')) {
960
- this.prevMonth();
961
- }
962
- else if (target.closest('.month-next')) {
963
- this.nextMonth();
964
- }
965
- }
966
- }
967
-
968
- _handleClearClick = () => {
969
- this.date = null;
970
- this.setInputValue();
971
- this.close();
972
- }
973
-
974
- _handleMonthChange = (e) => {
975
- this.gotoMonth(e.target.value);
976
- }
977
-
978
- _handleYearChange = (e) => {
979
- this.gotoYear(e.target.value);
980
- }
981
-
982
- // change view to a specific month (zero-index, e.g. 0: January)
983
- gotoMonth(month) {
984
- if (!isNaN(month)) {
985
- this.calendars[0].month = parseInt(month, 10);
986
- this.adjustCalendars();
987
- }
988
- }
989
-
990
- // change view to a specific full year (e.g. "2012")
991
- gotoYear(year) {
992
- if (!isNaN(year)) {
993
- this.calendars[0].year = parseInt(year, 10);
994
- this.adjustCalendars();
995
- }
996
- }
997
-
998
- _handleInputChange = (e: Event) => {
999
- let date;
1000
- // Prevent change event from being fired when triggered by the plugin
1001
- if (e['detail']?.firedBy === this) return;
1002
- if (this.options.parse) {
1003
- date = this.options.parse(this.el.value,
1004
- typeof this.options.format === "function"
1005
- ? this.options.format(new Date(this.el.value))
1006
- : this.options.format);
1007
- }
1008
- else {
1009
- date = new Date(Date.parse(this.el.value));
1010
- }
1011
- if (Datepicker._isDate(date)) this.setDate(date);
1012
- }
1013
-
1014
- renderDayName(opts, day, abbr: boolean = false) {
1015
- day += opts.firstDay;
1016
- while (day >= 7) {
1017
- day -= 7;
1018
- }
1019
- return abbr ? opts.i18n.weekdaysAbbrev[day] : opts.i18n.weekdays[day];
1020
- }
1021
-
1022
- // Set input value to the selected date and close Datepicker
1023
- _finishSelection = () => {
1024
- this.setInputValue();
1025
- this.close();
1026
- }
1027
-
1028
- /**
1029
- * Open datepicker.
1030
- */
1031
- open = () => {
1032
- if (this.isOpen) return;
1033
- this.isOpen = true;
1034
- if (typeof this.options.onOpen === 'function') {
1035
- this.options.onOpen.call(this);
1036
- }
1037
- this.draw();
1038
- this.modal.open(undefined);
1039
- return this;
1040
- }
1041
-
1042
- /**
1043
- * Close datepicker.
1044
- */
1045
- close = () => {
1046
- if (!this.isOpen) return;
1047
- this.isOpen = false;
1048
- if (typeof this.options.onClose === 'function') {
1049
- this.options.onClose.call(this);
1050
- }
1051
- this.modal.close();
1052
- return this;
1053
- }
1054
-
1055
- static {
1056
- Datepicker._template = `
1057
- <div class="modal datepicker-modal">
1058
- <div class="modal-content datepicker-container">
1059
- <div class="datepicker-date-display">
1060
- <span class="year-text"></span>
1061
- <span class="date-text"></span>
1062
- </div>
1063
- <div class="datepicker-calendar-container">
1064
- <div class="datepicker-calendar"></div>
1065
- <div class="datepicker-footer">
1066
- <button class="btn-flat datepicker-clear waves-effect" style="visibility: hidden;" type="button"></button>
1067
- <div class="confirmation-btns">
1068
- <button class="btn-flat datepicker-cancel waves-effect" type="button"></button>
1069
- <button class="btn-flat datepicker-done waves-effect" type="button"></button>
1070
- </div>
1071
- </div>
1072
- </div>
1073
- </div>
1074
- </div>`;
1075
- }
1076
- }