UNPKG

174 kBJavaScriptView Raw
1import { ɵɵdefineInjectable, Injectable, EventEmitter, Component, Renderer2, ElementRef, Directive, ViewContainerRef, Input, Output, forwardRef, Host, ChangeDetectorRef, ViewChild, ChangeDetectionStrategy, NgModule } from '@angular/core';
2import { filter, map, take, takeUntil, distinctUntilChanged } from 'rxjs/operators';
3import { isFirstDayOfWeek, getDay, shiftDate, isBefore, endOf, isAfter, startOf, isArray, isSame, getFirstDayOfMonth, formatDate, getLocale, isSameMonth, isSameDay, isDisabledDay, isSameYear, isDateValid, setFullDate, getMonth, getFullYear, isDate, parseDate, utcAsLocal } from 'ngx-bootstrap/chronos';
4import { PositioningService } from 'ngx-bootstrap/positioning';
5import { trigger, state, style, transition, animate } from '@angular/animations';
6import { Subscription, BehaviorSubject, combineLatest, Subject } from 'rxjs';
7import { MiniStore, MiniState } from 'ngx-bootstrap/mini-ngrx';
8import { ComponentLoaderFactory } from 'ngx-bootstrap/component-loader';
9import { NG_VALUE_ACCESSOR, NG_VALIDATORS, FormsModule } from '@angular/forms';
10import { isBs3 } from 'ngx-bootstrap/utils';
11import { CommonModule } from '@angular/common';
12import { TooltipModule } from 'ngx-bootstrap/tooltip';
13
14/**
15 * For date range picker there are `BsDaterangepickerConfig` which inherits all properties,
16 * except `displayMonths`, for range picker it default to `2`
17 */
18class BsDatepickerConfig {
19 constructor() {
20 /** sets use adaptive position */
21 this.adaptivePosition = false;
22 /** sets use UTC date time format */
23 this.useUtc = false;
24 /** turn on/off animation */
25 this.isAnimated = false;
26 /**
27 * The view that the datepicker should start in
28 */
29 this.startView = 'day';
30 /**
31 * If true, returns focus to the datepicker / daterangepicker input after date selection
32 */
33 this.returnFocusToInput = false;
34 /** CSS class which will be applied to datepicker container,
35 * usually used to set color theme
36 */
37 this.containerClass = 'theme-green';
38 // DatepickerRenderOptions
39 this.displayMonths = 1;
40 /**
41 * Allows to hide week numbers in datepicker
42 */
43 this.showWeekNumbers = true;
44 this.dateInputFormat = 'L';
45 // range picker
46 this.rangeSeparator = ' - ';
47 /**
48 * Date format for date range input field
49 */
50 this.rangeInputFormat = 'L';
51 // DatepickerFormatOptions
52 this.monthTitle = 'MMMM';
53 this.yearTitle = 'YYYY';
54 this.dayLabel = 'D';
55 this.monthLabel = 'MMMM';
56 this.yearLabel = 'YYYY';
57 this.weekNumbers = 'w';
58 /**
59 * Shows 'today' button
60 */
61 this.showTodayButton = false;
62 /**
63 * Shows clear button
64 */
65 this.showClearButton = false;
66 /**
67 * Positioning of 'today' button
68 */
69 this.todayPosition = 'center';
70 /**
71 * Positioning of 'clear' button
72 */
73 this.clearPosition = 'right';
74 /**
75 * Label for 'today' button
76 */
77 this.todayButtonLabel = 'Today';
78 /**
79 * Label for 'clear' button
80 */
81 this.clearButtonLabel = 'Clear';
82 /**
83 * Label for 'custom range' button
84 */
85 this.customRangeButtonLabel = 'Custom Range';
86 }
87}
88BsDatepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDatepickerConfig_Factory() { return new BsDatepickerConfig(); }, token: BsDatepickerConfig, providedIn: "root" });
89BsDatepickerConfig.decorators = [
90 { type: Injectable, args: [{
91 providedIn: 'root'
92 },] }
93];
94
95const DATEPICKER_ANIMATION_TIMING = '220ms cubic-bezier(0, 0, 0.2, 1)';
96const datepickerAnimation = trigger('datepickerAnimation', [
97 state('animated-down', style({ height: '*', overflow: 'hidden' })),
98 transition('* => animated-down', [
99 style({ height: 0, overflow: 'hidden' }),
100 animate(DATEPICKER_ANIMATION_TIMING)
101 ]),
102 state('animated-up', style({ height: '*', overflow: 'hidden' })),
103 transition('* => animated-up', [
104 style({ height: '*', overflow: 'hidden' }),
105 animate(DATEPICKER_ANIMATION_TIMING)
106 ]),
107 transition('* => unanimated', animate('0s'))
108]);
109
110class BsDatepickerAbstractComponent {
111 constructor() {
112 this.containerClass = '';
113 this.customRanges = [];
114 this.chosenRange = [];
115 this._daysCalendarSub = new Subscription();
116 }
117 set minDate(value) {
118 var _a;
119 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMinDate(value);
120 }
121 set maxDate(value) {
122 var _a;
123 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMaxDate(value);
124 }
125 set daysDisabled(value) {
126 var _a;
127 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDaysDisabled(value);
128 }
129 set datesDisabled(value) {
130 var _a;
131 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDatesDisabled(value);
132 }
133 set datesEnabled(value) {
134 var _a;
135 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDatesEnabled(value);
136 }
137 set isDisabled(value) {
138 var _a;
139 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDisabled(value);
140 }
141 set dateCustomClasses(value) {
142 var _a;
143 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDateCustomClasses(value);
144 }
145 set dateTooltipTexts(value) {
146 var _a;
147 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setDateTooltipTexts(value);
148 }
149 set daysCalendar$(value) {
150 this._daysCalendar$ = value;
151 this._daysCalendarSub.unsubscribe();
152 this._daysCalendarSub.add(this._daysCalendar$.subscribe(value => {
153 this.multipleCalendars = !!value && value.length > 1;
154 }));
155 }
156 get daysCalendar$() {
157 return this._daysCalendar$;
158 }
159 // todo: valorkin fix
160 // eslint-disable-next-line @typescript-eslint/no-unused-vars,@typescript-eslint/no-empty-function
161 setViewMode(event) { }
162 // eslint-disable-next-line
163 navigateTo(event) { }
164 // eslint-disable-next-line
165 dayHoverHandler(event) { }
166 // eslint-disable-next-line
167 weekHoverHandler(event) { }
168 // eslint-disable-next-line
169 monthHoverHandler(event) { }
170 // eslint-disable-next-line
171 yearHoverHandler(event) { }
172 // eslint-disable-next-line
173 daySelectHandler(day) { }
174 // eslint-disable-next-line
175 monthSelectHandler(event) { }
176 // eslint-disable-next-line
177 yearSelectHandler(event) { }
178 // eslint-disable-next-line
179 setRangeOnCalendar(dates) { }
180 // eslint-disable-next-line
181 setToday() { }
182 // eslint-disable-next-line
183 clearDate() { }
184 // eslint-disable-next-line @typescript-eslint/no-explicit-any
185 _stopPropagation(event) {
186 event.stopPropagation();
187 }
188}
189
190class BsDatepickerActions {
191 calculate() {
192 return { type: BsDatepickerActions.CALCULATE };
193 }
194 format() {
195 return { type: BsDatepickerActions.FORMAT };
196 }
197 flag() {
198 return { type: BsDatepickerActions.FLAG };
199 }
200 select(date) {
201 return {
202 type: BsDatepickerActions.SELECT,
203 payload: date
204 };
205 }
206 changeViewMode(event) {
207 return {
208 type: BsDatepickerActions.CHANGE_VIEWMODE,
209 payload: event
210 };
211 }
212 navigateTo(event) {
213 return {
214 type: BsDatepickerActions.NAVIGATE_TO,
215 payload: event
216 };
217 }
218 navigateStep(step) {
219 return {
220 type: BsDatepickerActions.NAVIGATE_OFFSET,
221 payload: step
222 };
223 }
224 setOptions(options) {
225 return {
226 type: BsDatepickerActions.SET_OPTIONS,
227 payload: options
228 };
229 }
230 // date range picker
231 selectRange(value) {
232 return {
233 type: BsDatepickerActions.SELECT_RANGE,
234 payload: value
235 };
236 }
237 hoverDay(event) {
238 return {
239 type: BsDatepickerActions.HOVER,
240 payload: event.isHovered ? event.cell.date : null
241 };
242 }
243 minDate(date) {
244 return {
245 type: BsDatepickerActions.SET_MIN_DATE,
246 payload: date
247 };
248 }
249 maxDate(date) {
250 return {
251 type: BsDatepickerActions.SET_MAX_DATE,
252 payload: date
253 };
254 }
255 daysDisabled(days) {
256 return {
257 type: BsDatepickerActions.SET_DAYSDISABLED,
258 payload: days
259 };
260 }
261 datesDisabled(dates) {
262 return {
263 type: BsDatepickerActions.SET_DATESDISABLED,
264 payload: dates
265 };
266 }
267 datesEnabled(dates) {
268 return {
269 type: BsDatepickerActions.SET_DATESENABLED,
270 payload: dates
271 };
272 }
273 isDisabled(value) {
274 return {
275 type: BsDatepickerActions.SET_IS_DISABLED,
276 payload: value
277 };
278 }
279 setDateCustomClasses(value) {
280 return {
281 type: BsDatepickerActions.SET_DATE_CUSTOM_CLASSES,
282 payload: value
283 };
284 }
285 setDateTooltipTexts(value) {
286 return {
287 type: BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS,
288 payload: value
289 };
290 }
291 setLocale(locale) {
292 return {
293 type: BsDatepickerActions.SET_LOCALE,
294 payload: locale
295 };
296 }
297}
298BsDatepickerActions.CALCULATE = '[datepicker] calculate dates matrix';
299BsDatepickerActions.FORMAT = '[datepicker] format datepicker values';
300BsDatepickerActions.FLAG = '[datepicker] set flags';
301BsDatepickerActions.SELECT = '[datepicker] select date';
302BsDatepickerActions.NAVIGATE_OFFSET = '[datepicker] shift view date';
303BsDatepickerActions.NAVIGATE_TO = '[datepicker] change view date';
304BsDatepickerActions.SET_OPTIONS = '[datepicker] update render options';
305BsDatepickerActions.HOVER = '[datepicker] hover date';
306BsDatepickerActions.CHANGE_VIEWMODE = '[datepicker] switch view mode';
307BsDatepickerActions.SET_MIN_DATE = '[datepicker] set min date';
308BsDatepickerActions.SET_MAX_DATE = '[datepicker] set max date';
309BsDatepickerActions.SET_DAYSDISABLED = '[datepicker] set days disabled';
310BsDatepickerActions.SET_DATESDISABLED = '[datepicker] set dates disabled';
311BsDatepickerActions.SET_DATESENABLED = '[datepicker] set dates enabled';
312BsDatepickerActions.SET_IS_DISABLED = '[datepicker] set is disabled';
313BsDatepickerActions.SET_DATE_CUSTOM_CLASSES = '[datepicker] set date custom classes';
314BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS = '[datepicker] set date tooltip texts';
315BsDatepickerActions.SET_LOCALE = '[datepicker] set datepicker locale';
316BsDatepickerActions.SELECT_RANGE = '[daterangepicker] select dates range';
317BsDatepickerActions.decorators = [
318 { type: Injectable }
319];
320
321class BsLocaleService {
322 constructor() {
323 this._defaultLocale = 'en';
324 this._locale = new BehaviorSubject(this._defaultLocale);
325 this._localeChange = this._locale.asObservable();
326 }
327 get locale() {
328 return this._locale;
329 }
330 get localeChange() {
331 return this._localeChange;
332 }
333 get currentLocale() {
334 return this._locale.getValue();
335 }
336 use(locale) {
337 if (locale === this.currentLocale) {
338 return;
339 }
340 this._locale.next(locale);
341 }
342}
343BsLocaleService.decorators = [
344 { type: Injectable }
345];
346
347class BsDatepickerEffects {
348 constructor(_actions, _localeService) {
349 this._actions = _actions;
350 this._localeService = _localeService;
351 this._subs = [];
352 }
353 init(_bsDatepickerStore) {
354 this._store = _bsDatepickerStore;
355 return this;
356 }
357 /** setters */
358 setValue(value) {
359 var _a;
360 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.select(value));
361 }
362 setRangeValue(value) {
363 var _a;
364 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.selectRange(value));
365 }
366 setMinDate(value) {
367 var _a;
368 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.minDate(value));
369 return this;
370 }
371 setMaxDate(value) {
372 var _a;
373 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.maxDate(value));
374 return this;
375 }
376 setDaysDisabled(value) {
377 var _a;
378 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.daysDisabled(value));
379 return this;
380 }
381 setDatesDisabled(value) {
382 var _a;
383 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.datesDisabled(value));
384 return this;
385 }
386 setDatesEnabled(value) {
387 var _a;
388 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.datesEnabled(value));
389 return this;
390 }
391 setDisabled(value) {
392 var _a;
393 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.isDisabled(value));
394 return this;
395 }
396 setDateCustomClasses(value) {
397 var _a;
398 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setDateCustomClasses(value));
399 return this;
400 }
401 setDateTooltipTexts(value) {
402 var _a;
403 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setDateTooltipTexts(value));
404 return this;
405 }
406 /* Set rendering options */
407 setOptions(_config) {
408 var _a;
409 const _options = Object.assign({ locale: this._localeService.currentLocale }, _config);
410 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setOptions(_options));
411 return this;
412 }
413 /** view to mode bindings */
414 setBindings(container) {
415 if (!this._store) {
416 return this;
417 }
418 container.daysCalendar$ = this._store.select(state => state.flaggedMonths)
419 .pipe(filter(months => !!months));
420 // month calendar
421 container.monthsCalendar = this._store.select(state => state.flaggedMonthsCalendar)
422 .pipe(filter(months => !!months));
423 // year calendar
424 container.yearsCalendar = this._store.select(state => state.yearsCalendarFlagged)
425 .pipe(filter(years => !!years));
426 container.viewMode = this._store.select(state => { var _a; return (_a = state.view) === null || _a === void 0 ? void 0 : _a.mode; });
427 container.options$ = combineLatest([
428 this._store.select(state => state.showWeekNumbers),
429 this._store.select(state => state.displayMonths)
430 ])
431 .pipe(map((latest) => ({
432 showWeekNumbers: latest[0],
433 displayMonths: latest[1]
434 })));
435 return this;
436 }
437 /** event handlers */
438 setEventHandlers(container) {
439 container.setViewMode = (event) => {
440 var _a;
441 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.changeViewMode(event));
442 };
443 container.navigateTo = (event) => {
444 var _a;
445 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.navigateStep(event.step));
446 };
447 container.dayHoverHandler = (event) => {
448 var _a;
449 const _cell = event.cell;
450 if (_cell.isOtherMonth || _cell.isDisabled) {
451 return;
452 }
453 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.hoverDay(event));
454 _cell.isHovered = event.isHovered;
455 };
456 container.monthHoverHandler = (event) => {
457 event.cell.isHovered = event.isHovered;
458 };
459 container.yearHoverHandler = (event) => {
460 event.cell.isHovered = event.isHovered;
461 };
462 return this;
463 }
464 registerDatepickerSideEffects() {
465 if (!this._store) {
466 return this;
467 }
468 this._subs.push(this._store.select(state => state.view).subscribe(() => {
469 var _a;
470 (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.calculate());
471 }));
472 // format calendar values on month model change
473 this._subs.push(this._store
474 .select(state => state.monthsModel)
475 .pipe(filter(monthModel => !!monthModel))
476 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.format()); }));
477 // flag day values
478 this._subs.push(this._store
479 .select(state => state.formattedMonths)
480 .pipe(filter(month => !!month))
481 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
482 // flag day values
483 this._subs.push(this._store
484 .select(state => state.selectedDate)
485 .pipe(filter(selectedDate => !!selectedDate))
486 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
487 // flag for date range picker
488 this._subs.push(this._store
489 .select(state => state.selectedRange)
490 .pipe(filter(selectedRange => !!selectedRange))
491 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
492 // monthsCalendar
493 this._subs.push(this._store
494 .select(state => state.monthsCalendar)
495 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
496 // years calendar
497 this._subs.push(this._store
498 .select(state => state.yearsCalendarModel)
499 .pipe(filter(state => !!state))
500 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
501 // on hover
502 this._subs.push(this._store
503 .select(state => state.hoveredDate)
504 .pipe(filter(hoveredDate => !!hoveredDate))
505 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
506 // date custom classes
507 this._subs.push(this._store
508 .select(state => state.dateCustomClasses)
509 .pipe(filter(dateCustomClasses => !!dateCustomClasses))
510 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
511 // date tooltip texts
512 this._subs.push(this._store
513 .select(state => state.dateTooltipTexts)
514 .pipe(filter(dateTooltipTexts => !!dateTooltipTexts))
515 .subscribe(() => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.flag()); }));
516 // on locale change
517 this._subs.push(this._localeService.localeChange
518 .subscribe(locale => { var _a; return (_a = this._store) === null || _a === void 0 ? void 0 : _a.dispatch(this._actions.setLocale(locale)); }));
519 return this;
520 }
521 destroy() {
522 for (const sub of this._subs) {
523 sub.unsubscribe();
524 }
525 }
526}
527BsDatepickerEffects.decorators = [
528 { type: Injectable }
529];
530BsDatepickerEffects.ctorParameters = () => [
531 { type: BsDatepickerActions },
532 { type: BsLocaleService }
533];
534
535const defaultMonthOptions = {
536 width: 7,
537 height: 6
538};
539const dayInMilliseconds = 24 * 60 * 60 * 1000;
540
541class BsDatepickerState {
542 constructor() {
543 // DatepickerRenderOptions
544 this.showWeekNumbers = true;
545 this.displayMonths = 1;
546 }
547}
548const _initialView = { date: new Date(), mode: 'day' };
549const initialDatepickerState = Object.assign(new BsDatepickerConfig(), {
550 locale: 'en',
551 view: _initialView,
552 selectedRange: [],
553 monthViewOptions: defaultMonthOptions
554});
555
556function getStartingDayOfCalendar(date, options) {
557 if (isFirstDayOfWeek(date, options.firstDayOfWeek)) {
558 return date;
559 }
560 const weekDay = getDay(date);
561 const offset = calculateDateOffset(weekDay, options.firstDayOfWeek);
562 return shiftDate(date, { day: -offset });
563}
564function calculateDateOffset(weekday, startingDayOffset) {
565 const _startingDayOffset = Number(startingDayOffset);
566 if (isNaN(_startingDayOffset)) {
567 return 0;
568 }
569 if (_startingDayOffset === 0) {
570 return weekday;
571 }
572 const offset = weekday - _startingDayOffset % 7;
573 return offset < 0 ? offset + 7 : offset;
574}
575function isMonthDisabled(date, min, max) {
576 const minBound = min && isBefore(endOf(date, 'month'), min, 'day');
577 const maxBound = max && isAfter(startOf(date, 'month'), max, 'day');
578 return minBound || maxBound || false;
579}
580function isYearDisabled(date, min, max) {
581 const minBound = min && isBefore(endOf(date, 'year'), min, 'day');
582 const maxBound = max && isAfter(startOf(date, 'year'), max, 'day');
583 return minBound || maxBound || false;
584}
585function isDisabledDate(date, datesDisabled) {
586 if (!datesDisabled || !isArray(datesDisabled) || !datesDisabled.length) {
587 return false;
588 }
589 return datesDisabled.some((dateDisabled) => isSame(date, dateDisabled, 'date'));
590}
591function isEnabledDate(date, datesEnabled) {
592 if (!datesEnabled || !isArray(datesEnabled) || !datesEnabled.length) {
593 return false;
594 }
595 return !datesEnabled.some((enabledDate) => isSame(date, enabledDate, 'date'));
596}
597function getYearsCalendarInitialDate(state, calendarIndex = 0) {
598 const model = state && state.yearsCalendarModel && state.yearsCalendarModel[calendarIndex];
599 return (model === null || model === void 0 ? void 0 : model.years[0]) && model.years[0][0] && model.years[0][0].date;
600}
601function checkRangesWithMaxDate(ranges, maxDate) {
602 if (!ranges)
603 return ranges;
604 if (!maxDate)
605 return ranges;
606 if (!ranges.length && !ranges[0].value)
607 return ranges;
608 ranges.forEach((item) => {
609 if (!item || !item.value)
610 return ranges;
611 if (item.value instanceof Date)
612 return ranges;
613 if (!(item.value instanceof Array && item.value.length))
614 return ranges;
615 item.value = compareDateWithMaxDateHelper(item.value, maxDate);
616 return ranges;
617 });
618 return ranges;
619}
620function checkBsValue(date, maxDate) {
621 if (!date)
622 return date;
623 if (!maxDate)
624 return date;
625 if (date instanceof Array && !date.length)
626 return date;
627 if (date instanceof Date)
628 return date;
629 return compareDateWithMaxDateHelper(date, maxDate);
630}
631function compareDateWithMaxDateHelper(date, maxDate) {
632 if (date instanceof Array) {
633 const editedValues = date.map(item => {
634 if (!item)
635 return item;
636 if (isAfter(item, maxDate, 'date'))
637 item = maxDate;
638 return item;
639 });
640 return editedValues;
641 }
642 return date;
643}
644
645function createMatrix(options, fn) {
646 let prevValue = options.initialDate;
647 const matrix = new Array(options.height);
648 for (let i = 0; i < options.height; i++) {
649 matrix[i] = new Array(options.width);
650 for (let j = 0; j < options.width; j++) {
651 matrix[i][j] = fn(prevValue);
652 prevValue = shiftDate(prevValue, options.shift);
653 }
654 }
655 return matrix;
656}
657
658// user and model input should handle parsing and validating input values
659function calcDaysCalendar(startingDate, options) {
660 const firstDay = getFirstDayOfMonth(startingDate);
661 const initialDate = getStartingDayOfCalendar(firstDay, options);
662 // todo test
663 const matrixOptions = {
664 width: options.width || 0,
665 height: options.height || 0,
666 initialDate,
667 shift: { day: 1 }
668 };
669 const daysMatrix = createMatrix(matrixOptions, date => date);
670 return {
671 daysMatrix,
672 month: firstDay
673 };
674}
675
676function formatDaysCalendar(daysCalendar, formatOptions, monthIndex) {
677 return {
678 month: daysCalendar.month,
679 monthTitle: formatDate(daysCalendar.month, formatOptions.monthTitle, formatOptions.locale),
680 yearTitle: formatDate(daysCalendar.month, formatOptions.yearTitle, formatOptions.locale),
681 weekNumbers: getWeekNumbers(daysCalendar.daysMatrix, formatOptions.weekNumbers, formatOptions.locale),
682 weekdays: getShiftedWeekdays(formatOptions.locale),
683 weeks: daysCalendar.daysMatrix.map((week, weekIndex) => ({
684 days: week.map((date, dayIndex) => ({
685 date,
686 label: formatDate(date, formatOptions.dayLabel, formatOptions.locale),
687 monthIndex,
688 weekIndex,
689 dayIndex
690 }))
691 })),
692 hideLeftArrow: false,
693 hideRightArrow: false,
694 disableLeftArrow: false,
695 disableRightArrow: false
696 };
697}
698function getWeekNumbers(daysMatrix, format, locale) {
699 return daysMatrix.map((days) => (days[0] ? formatDate(days[0], format, locale) : ''));
700}
701function getShiftedWeekdays(locale) {
702 const _locale = getLocale(locale);
703 const weekdays = _locale.weekdaysShort();
704 const firstDayOfWeek = _locale.firstDayOfWeek();
705 return [...weekdays.slice(firstDayOfWeek), ...weekdays.slice(0, firstDayOfWeek)];
706}
707
708function flagDaysCalendar(formattedMonth, options) {
709 formattedMonth.weeks.forEach((week) => {
710 week.days.forEach((day, dayIndex) => {
711 // datepicker
712 const isOtherMonth = !isSameMonth(day.date, formattedMonth.month);
713 const isHovered = !isOtherMonth && isSameDay(day.date, options.hoveredDate);
714 // date range picker
715 const isSelectionStart = !isOtherMonth &&
716 options.selectedRange &&
717 isSameDay(day.date, options.selectedRange[0]);
718 const isSelectionEnd = !isOtherMonth &&
719 options.selectedRange &&
720 isSameDay(day.date, options.selectedRange[1]);
721 const isSelected = (!isOtherMonth && isSameDay(day.date, options.selectedDate)) ||
722 isSelectionStart ||
723 isSelectionEnd;
724 const isInRange = !isOtherMonth &&
725 options.selectedRange &&
726 isDateInRange(day.date, options.selectedRange, options.hoveredDate);
727 const isDisabled = options.isDisabled ||
728 isBefore(day.date, options.minDate, 'day') ||
729 isAfter(day.date, options.maxDate, 'day') ||
730 isDisabledDay(day.date, options.daysDisabled) ||
731 isDisabledDate(day.date, options.datesDisabled) ||
732 isEnabledDate(day.date, options.datesEnabled);
733 const currentDate = new Date();
734 const isToday = !isOtherMonth && isSameDay(day.date, currentDate);
735 const customClasses = options.dateCustomClasses && options.dateCustomClasses
736 .map(dcc => isSameDay(day.date, dcc.date) ? dcc.classes : [])
737 .reduce((previousValue, currentValue) => previousValue.concat(currentValue), [])
738 .join(' ')
739 || '';
740 const tooltipText = options.dateTooltipTexts && options.dateTooltipTexts
741 .map(tt => isSameDay(day.date, tt.date) ? tt.tooltipText : '')
742 .reduce((previousValue, currentValue) => {
743 previousValue.push(currentValue);
744 return previousValue;
745 }, [])
746 .join(' ')
747 || '';
748 // decide update or not
749 const newDay = Object.assign({}, day, {
750 isOtherMonth,
751 isHovered,
752 isSelected,
753 isSelectionStart,
754 isSelectionEnd,
755 isInRange,
756 isDisabled,
757 isToday,
758 customClasses,
759 tooltipText
760 });
761 if (day.isOtherMonth !== newDay.isOtherMonth ||
762 day.isHovered !== newDay.isHovered ||
763 day.isSelected !== newDay.isSelected ||
764 day.isSelectionStart !== newDay.isSelectionStart ||
765 day.isSelectionEnd !== newDay.isSelectionEnd ||
766 day.isDisabled !== newDay.isDisabled ||
767 day.isInRange !== newDay.isInRange ||
768 day.customClasses !== newDay.customClasses ||
769 day.tooltipText !== newDay.tooltipText) {
770 week.days[dayIndex] = newDay;
771 }
772 });
773 });
774 // todo: add check for linked calendars
775 formattedMonth.hideLeftArrow =
776 options.isDisabled ||
777 (!!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths);
778 formattedMonth.hideRightArrow =
779 options.isDisabled ||
780 ((!!options.monthIndex || options.monthIndex === 0) && !!options.displayMonths && options.monthIndex < options.displayMonths &&
781 options.monthIndex + 1 !== options.displayMonths);
782 formattedMonth.disableLeftArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: -1 }), options.minDate, options.maxDate);
783 formattedMonth.disableRightArrow = isMonthDisabled(shiftDate(formattedMonth.month, { month: 1 }), options.minDate, options.maxDate);
784 return formattedMonth;
785}
786function isDateInRange(date, selectedRange, hoveredDate) {
787 if (!date || !selectedRange || !selectedRange[0]) {
788 return false;
789 }
790 if (selectedRange[1]) {
791 return date > selectedRange[0] && date <= selectedRange[1];
792 }
793 if (hoveredDate) {
794 return date > selectedRange[0] && date <= hoveredDate;
795 }
796 return false;
797}
798
799function canSwitchMode(mode, minMode) {
800 return minMode ? mode >= minMode : true;
801}
802
803const height = 4;
804const width = 3;
805const shift = { month: 1 };
806function formatMonthsCalendar(viewDate, formatOptions) {
807 const initialDate = startOf(viewDate, 'year');
808 const matrixOptions = { width, height, initialDate, shift };
809 const monthMatrix = createMatrix(matrixOptions, date => ({
810 date,
811 label: formatDate(date, formatOptions.monthLabel, formatOptions.locale)
812 }));
813 return {
814 months: monthMatrix,
815 monthTitle: '',
816 yearTitle: formatDate(viewDate, formatOptions.yearTitle, formatOptions.locale),
817 hideRightArrow: false,
818 hideLeftArrow: false,
819 disableRightArrow: false,
820 disableLeftArrow: false
821 };
822}
823
824function flagMonthsCalendar(monthCalendar, options) {
825 monthCalendar.months.forEach((months, rowIndex) => {
826 months.forEach((month, monthIndex) => {
827 let isSelected;
828 const isHovered = isSameMonth(month.date, options.hoveredMonth);
829 const isDisabled = options.isDisabled ||
830 isMonthDisabled(month.date, options.minDate, options.maxDate);
831 if (!options.selectedDate && options.selectedRange) {
832 isSelected = isSameMonth(month.date, options.selectedRange[0]);
833 if (!isSelected) {
834 isSelected = isSameMonth(month.date, options.selectedRange[1]);
835 }
836 }
837 else {
838 isSelected = isSameMonth(month.date, options.selectedDate);
839 }
840 const newMonth = Object.assign(/*{},*/ month, {
841 isHovered,
842 isDisabled,
843 isSelected
844 });
845 if (month.isHovered !== newMonth.isHovered ||
846 month.isDisabled !== newMonth.isDisabled ||
847 month.isSelected !== newMonth.isSelected) {
848 monthCalendar.months[rowIndex][monthIndex] = newMonth;
849 }
850 });
851 });
852 // todo: add check for linked calendars
853 monthCalendar.hideLeftArrow =
854 !!options.monthIndex && options.monthIndex > 0 && options.monthIndex !== options.displayMonths;
855 monthCalendar.hideRightArrow =
856 (!!options.monthIndex || options.monthIndex === 0)
857 && (!!options.displayMonths || options.displayMonths === 0)
858 && options.monthIndex < options.displayMonths
859 && options.monthIndex + 1 !== options.displayMonths;
860 monthCalendar.disableLeftArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: -1 }), options.minDate, options.maxDate);
861 monthCalendar.disableRightArrow = isYearDisabled(shiftDate(monthCalendar.months[0][0].date, { year: 1 }), options.minDate, options.maxDate);
862 return monthCalendar;
863}
864
865const height$1 = 4;
866const width$1 = 4;
867const yearsPerCalendar = height$1 * width$1;
868const initialYearShift = (Math.floor(yearsPerCalendar / 2) - 1) * -1;
869const shift$1 = { year: 1 };
870function formatYearsCalendar(viewDate, formatOptions, previousInitialDate) {
871 const initialDate = calculateInitialDate(viewDate, previousInitialDate);
872 const matrixOptions = { width: width$1, height: height$1, initialDate, shift: shift$1 };
873 const yearsMatrix = createMatrix(matrixOptions, date => ({
874 date,
875 label: formatDate(date, formatOptions.yearLabel, formatOptions.locale)
876 }));
877 const yearTitle = formatYearRangeTitle(yearsMatrix, formatOptions);
878 return {
879 years: yearsMatrix,
880 monthTitle: '',
881 yearTitle,
882 hideLeftArrow: false,
883 hideRightArrow: false,
884 disableLeftArrow: false,
885 disableRightArrow: false
886 };
887}
888function calculateInitialDate(viewDate, previousInitialDate) {
889 if (previousInitialDate
890 && viewDate.getFullYear() >= previousInitialDate.getFullYear()
891 && viewDate.getFullYear() < previousInitialDate.getFullYear() + yearsPerCalendar) {
892 return previousInitialDate;
893 }
894 return shiftDate(viewDate, { year: initialYearShift });
895}
896function formatYearRangeTitle(yearsMatrix, formatOptions) {
897 const from = formatDate(yearsMatrix[0][0].date, formatOptions.yearTitle, formatOptions.locale);
898 const to = formatDate(yearsMatrix[height$1 - 1][width$1 - 1].date, formatOptions.yearTitle, formatOptions.locale);
899 return `${from} - ${to}`;
900}
901
902function flagYearsCalendar(yearsCalendar, options) {
903 yearsCalendar.years.forEach((years, rowIndex) => {
904 years.forEach((year, yearIndex) => {
905 let isSelected;
906 const isHovered = isSameYear(year.date, options.hoveredYear);
907 const isDisabled = options.isDisabled ||
908 isYearDisabled(year.date, options.minDate, options.maxDate);
909 if (!options.selectedDate && options.selectedRange) {
910 isSelected = isSameYear(year.date, options.selectedRange[0]);
911 if (!isSelected) {
912 isSelected = isSameYear(year.date, options.selectedRange[1]);
913 }
914 }
915 else {
916 isSelected = isSameYear(year.date, options.selectedDate);
917 }
918 const newMonth = Object.assign(/*{},*/ year, { isHovered, isDisabled, isSelected });
919 if (year.isHovered !== newMonth.isHovered ||
920 year.isDisabled !== newMonth.isDisabled ||
921 year.isSelected !== newMonth.isSelected) {
922 yearsCalendar.years[rowIndex][yearIndex] = newMonth;
923 }
924 });
925 });
926 // todo: add check for linked calendars
927 yearsCalendar.hideLeftArrow =
928 !!options.yearIndex && options.yearIndex > 0 && options.yearIndex !== options.displayMonths;
929 yearsCalendar.hideRightArrow =
930 !!options.yearIndex && !!options.displayMonths &&
931 options.yearIndex < options.displayMonths &&
932 options.yearIndex + 1 !== options.displayMonths;
933 yearsCalendar.disableLeftArrow = isYearDisabled(shiftDate(yearsCalendar.years[0][0].date, { year: -1 }), options.minDate, options.maxDate);
934 const i = yearsCalendar.years.length - 1;
935 const j = yearsCalendar.years[i].length - 1;
936 yearsCalendar.disableRightArrow = isYearDisabled(shiftDate(yearsCalendar.years[i][j].date, { year: 1 }), options.minDate, options.maxDate);
937 return yearsCalendar;
938}
939
940function bsDatepickerReducer(state = initialDatepickerState, action) {
941 switch (action.type) {
942 case BsDatepickerActions.CALCULATE: {
943 return calculateReducer(state);
944 }
945 case BsDatepickerActions.FORMAT: {
946 return formatReducer(state);
947 }
948 case BsDatepickerActions.FLAG: {
949 return flagReducer(state);
950 }
951 case BsDatepickerActions.NAVIGATE_OFFSET: {
952 return navigateOffsetReducer(state, action);
953 }
954 case BsDatepickerActions.NAVIGATE_TO: {
955 const payload = action.payload;
956 if (!state.view || !payload.unit) {
957 return state;
958 }
959 const date = setFullDate(state.view.date, payload.unit);
960 let newState;
961 let mode;
962 if (canSwitchMode(payload.viewMode, state.minMode)) {
963 mode = payload.viewMode;
964 newState = { view: { date, mode } };
965 }
966 else {
967 mode = state.view.mode;
968 newState = { selectedDate: date, view: { date, mode } };
969 }
970 return Object.assign({}, state, newState);
971 }
972 case BsDatepickerActions.CHANGE_VIEWMODE: {
973 if (!canSwitchMode(action.payload, state.minMode) || !state.view) {
974 return state;
975 }
976 const date = state.view.date;
977 const mode = action.payload;
978 const newState = { view: { date, mode } };
979 return Object.assign({}, state, newState);
980 }
981 case BsDatepickerActions.HOVER: {
982 return Object.assign({}, state, { hoveredDate: action.payload });
983 }
984 case BsDatepickerActions.SELECT: {
985 if (!state.view) {
986 return state;
987 }
988 const newState = {
989 selectedDate: action.payload,
990 view: state.view
991 };
992 const mode = state.view.mode;
993 const _date = action.payload || state.view.date;
994 const date = getViewDate(_date, state.minDate, state.maxDate);
995 newState.view = { mode, date };
996 return Object.assign({}, state, newState);
997 }
998 case BsDatepickerActions.SET_OPTIONS: {
999 if (!state.view) {
1000 return state;
1001 }
1002 const newState = action.payload;
1003 // preserve view mode
1004 const mode = newState.minMode ? newState.minMode : state.view.mode;
1005 const _viewDate = isDateValid(newState.value) && newState.value
1006 || isArray(newState.value) && isDateValid(newState.value[0]) && newState.value[0]
1007 || state.view.date;
1008 const date = getViewDate(_viewDate, newState.minDate, newState.maxDate);
1009 newState.view = { mode, date };
1010 // update selected value
1011 if (newState.value) {
1012 // if new value is array we work with date range
1013 if (isArray(newState.value)) {
1014 newState.selectedRange = newState.value;
1015 }
1016 // if new value is a date -> datepicker
1017 if (newState.value instanceof Date) {
1018 newState.selectedDate = newState.value;
1019 }
1020 // provided value is not supported :)
1021 // need to report it somehow
1022 }
1023 return Object.assign({}, state, newState);
1024 }
1025 // date range picker
1026 case BsDatepickerActions.SELECT_RANGE: {
1027 if (!state.view) {
1028 return state;
1029 }
1030 const newState = {
1031 selectedRange: action.payload,
1032 view: state.view
1033 };
1034 const mode = state.view.mode;
1035 const _date = action.payload && action.payload[0] || state.view.date;
1036 const date = getViewDate(_date, state.minDate, state.maxDate);
1037 newState.view = { mode, date };
1038 return Object.assign({}, state, newState);
1039 }
1040 case BsDatepickerActions.SET_MIN_DATE: {
1041 return Object.assign({}, state, {
1042 minDate: action.payload
1043 });
1044 }
1045 case BsDatepickerActions.SET_MAX_DATE: {
1046 return Object.assign({}, state, {
1047 maxDate: action.payload
1048 });
1049 }
1050 case BsDatepickerActions.SET_IS_DISABLED: {
1051 return Object.assign({}, state, {
1052 isDisabled: action.payload
1053 });
1054 }
1055 case BsDatepickerActions.SET_DATE_CUSTOM_CLASSES: {
1056 return Object.assign({}, state, {
1057 dateCustomClasses: action.payload
1058 });
1059 }
1060 case BsDatepickerActions.SET_DATE_TOOLTIP_TEXTS: {
1061 return Object.assign({}, state, {
1062 dateTooltipTexts: action.payload
1063 });
1064 }
1065 default:
1066 return state;
1067 }
1068}
1069function calculateReducer(state) {
1070 if (!state.view) {
1071 return state;
1072 }
1073 // how many calendars
1074 let displayMonths;
1075 if (state.displayOneMonthRange &&
1076 isDisplayOneMonth(state.view.date, state.minDate, state.maxDate)) {
1077 displayMonths = 1;
1078 }
1079 else {
1080 displayMonths = state.displayMonths || 1;
1081 }
1082 // use selected date on initial rendering if set
1083 let viewDate = state.view.date;
1084 if (state.view.mode === 'day' && state.monthViewOptions) {
1085 if (state.showPreviousMonth && state.selectedRange && state.selectedRange.length === 0) {
1086 viewDate = shiftDate(viewDate, { month: -1 });
1087 }
1088 state.monthViewOptions.firstDayOfWeek = getLocale(state.locale).firstDayOfWeek();
1089 let monthsModel = new Array(displayMonths);
1090 for (let monthIndex = 0; monthIndex < displayMonths; monthIndex++) {
1091 // todo: for unlinked calendars it will be harder
1092 monthsModel[monthIndex] = calcDaysCalendar(viewDate, state.monthViewOptions);
1093 viewDate = shiftDate(viewDate, { month: 1 });
1094 }
1095 // Check if parameter enabled and check if it's not months navigation event
1096 if (state.preventChangeToNextMonth && state.flaggedMonths && state.hoveredDate) {
1097 const viewMonth = calcDaysCalendar(state.view.date, state.monthViewOptions);
1098 // Check if viewed right month same as in flaggedMonths state, then override months model with flaggedMonths
1099 if (state.flaggedMonths.length && state.flaggedMonths[1].month.getMonth() === viewMonth.month.getMonth()) {
1100 monthsModel = state.flaggedMonths
1101 .map(item => {
1102 if (state.monthViewOptions) {
1103 return calcDaysCalendar(item.month, state.monthViewOptions);
1104 }
1105 return null;
1106 })
1107 .filter(item => item !== null);
1108 }
1109 }
1110 return Object.assign({}, state, { monthsModel });
1111 }
1112 if (state.view.mode === 'month') {
1113 const monthsCalendar = new Array(displayMonths);
1114 for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
1115 // todo: for unlinked calendars it will be harder
1116 monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
1117 viewDate = shiftDate(viewDate, { year: 1 });
1118 }
1119 return Object.assign({}, state, { monthsCalendar });
1120 }
1121 if (state.view.mode === 'year') {
1122 const yearsCalendarModel = new Array(displayMonths);
1123 for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
1124 // todo: for unlinked calendars it will be harder
1125 yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state), state.minMode === 'year' ? getYearsCalendarInitialDate(state, calendarIndex) : undefined);
1126 viewDate = shiftDate(viewDate, { year: yearsPerCalendar });
1127 }
1128 return Object.assign({}, state, { yearsCalendarModel });
1129 }
1130 return state;
1131}
1132function formatReducer(state) {
1133 if (!state.view) {
1134 return state;
1135 }
1136 if (state.view.mode === 'day' && state.monthsModel) {
1137 const formattedMonths = state.monthsModel.map((month, monthIndex) => formatDaysCalendar(month, getFormatOptions(state), monthIndex));
1138 return Object.assign({}, state, { formattedMonths });
1139 }
1140 // how many calendars
1141 const displayMonths = state.displayMonths || 1;
1142 // check initial rendering
1143 // use selected date on initial rendering if set
1144 let viewDate = state.view.date;
1145 if (state.view.mode === 'month') {
1146 const monthsCalendar = new Array(displayMonths);
1147 for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
1148 // todo: for unlinked calendars it will be harder
1149 monthsCalendar[calendarIndex] = formatMonthsCalendar(viewDate, getFormatOptions(state));
1150 viewDate = shiftDate(viewDate, { year: 1 });
1151 }
1152 return Object.assign({}, state, { monthsCalendar });
1153 }
1154 if (state.view.mode === 'year') {
1155 const yearsCalendarModel = new Array(displayMonths);
1156 for (let calendarIndex = 0; calendarIndex < displayMonths; calendarIndex++) {
1157 // todo: for unlinked calendars it will be harder
1158 yearsCalendarModel[calendarIndex] = formatYearsCalendar(viewDate, getFormatOptions(state));
1159 viewDate = shiftDate(viewDate, { year: 16 });
1160 }
1161 return Object.assign({}, state, { yearsCalendarModel });
1162 }
1163 return state;
1164}
1165function flagReducer(state) {
1166 if (!state.view) {
1167 return state;
1168 }
1169 const displayMonths = isDisplayOneMonth(state.view.date, state.minDate, state.maxDate) ? 1 : state.displayMonths;
1170 if (state.formattedMonths && state.view.mode === 'day') {
1171 const flaggedMonths = state.formattedMonths.map((formattedMonth, monthIndex) => flagDaysCalendar(formattedMonth, {
1172 isDisabled: state.isDisabled,
1173 minDate: state.minDate,
1174 maxDate: state.maxDate,
1175 daysDisabled: state.daysDisabled,
1176 datesDisabled: state.datesDisabled,
1177 datesEnabled: state.datesEnabled,
1178 hoveredDate: state.hoveredDate,
1179 selectedDate: state.selectedDate,
1180 selectedRange: state.selectedRange,
1181 displayMonths,
1182 dateCustomClasses: state.dateCustomClasses,
1183 dateTooltipTexts: state.dateTooltipTexts,
1184 monthIndex
1185 }));
1186 return Object.assign({}, state, { flaggedMonths });
1187 }
1188 if (state.view.mode === 'month' && state.monthsCalendar) {
1189 const flaggedMonthsCalendar = state.monthsCalendar.map((formattedMonth, monthIndex) => flagMonthsCalendar(formattedMonth, {
1190 isDisabled: state.isDisabled,
1191 minDate: state.minDate,
1192 maxDate: state.maxDate,
1193 hoveredMonth: state.hoveredMonth,
1194 selectedDate: state.selectedDate,
1195 selectedRange: state.selectedRange,
1196 displayMonths,
1197 monthIndex
1198 }));
1199 return Object.assign({}, state, { flaggedMonthsCalendar });
1200 }
1201 if (state.view.mode === 'year' && state.yearsCalendarModel) {
1202 const yearsCalendarFlagged = state.yearsCalendarModel.map((formattedMonth, yearIndex) => flagYearsCalendar(formattedMonth, {
1203 isDisabled: state.isDisabled,
1204 minDate: state.minDate,
1205 maxDate: state.maxDate,
1206 hoveredYear: state.hoveredYear,
1207 selectedDate: state.selectedDate,
1208 selectedRange: state.selectedRange,
1209 displayMonths,
1210 yearIndex
1211 }));
1212 return Object.assign({}, state, { yearsCalendarFlagged });
1213 }
1214 return state;
1215}
1216function navigateOffsetReducer(state, action) {
1217 if (!state.view) {
1218 return state;
1219 }
1220 const date = shiftViewDate(state, action);
1221 if (!date) {
1222 return state;
1223 }
1224 const newState = {
1225 view: {
1226 mode: state.view.mode,
1227 date
1228 }
1229 };
1230 return Object.assign({}, state, newState);
1231}
1232function shiftViewDate(state, action) {
1233 if (!state.view) {
1234 return undefined;
1235 }
1236 if (state.view.mode === 'year' && state.minMode === 'year') {
1237 const initialDate = getYearsCalendarInitialDate(state, 0);
1238 if (initialDate) {
1239 const middleDate = shiftDate(initialDate, { year: -initialYearShift });
1240 return shiftDate(middleDate, action.payload);
1241 }
1242 }
1243 return shiftDate(startOf(state.view.date, 'month'), action.payload);
1244}
1245function getFormatOptions(state) {
1246 return {
1247 locale: state.locale,
1248 monthTitle: state.monthTitle,
1249 yearTitle: state.yearTitle,
1250 dayLabel: state.dayLabel,
1251 monthLabel: state.monthLabel,
1252 yearLabel: state.yearLabel,
1253 weekNumbers: state.weekNumbers
1254 };
1255}
1256/**
1257 * if view date is provided (bsValue|ngModel) it should be shown
1258 * if view date is not provider:
1259 * if minDate>currentDate (default view value), show minDate
1260 * if maxDate<currentDate(default view value) show maxDate
1261 */
1262function getViewDate(viewDate, minDate, maxDate) {
1263 const _date = Array.isArray(viewDate) ? viewDate[0] : viewDate;
1264 if (minDate && isAfter(minDate, _date, 'day')) {
1265 return minDate;
1266 }
1267 if (maxDate && isBefore(maxDate, _date, 'day')) {
1268 return maxDate;
1269 }
1270 return _date;
1271}
1272function isDisplayOneMonth(viewDate, minDate, maxDate) {
1273 if (maxDate && isSame(maxDate, viewDate, 'day')) {
1274 return true;
1275 }
1276 return minDate && maxDate && minDate.getMonth() === maxDate.getMonth();
1277}
1278
1279class BsDatepickerStore extends MiniStore {
1280 constructor() {
1281 const _dispatcher = new BehaviorSubject({
1282 type: '[datepicker] dispatcher init'
1283 });
1284 const state = new MiniState(initialDatepickerState, _dispatcher, bsDatepickerReducer);
1285 super(_dispatcher, bsDatepickerReducer, state);
1286 }
1287}
1288BsDatepickerStore.decorators = [
1289 { type: Injectable }
1290];
1291BsDatepickerStore.ctorParameters = () => [];
1292
1293class BsDatepickerContainerComponent extends BsDatepickerAbstractComponent {
1294 constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
1295 super();
1296 this._config = _config;
1297 this._store = _store;
1298 this._element = _element;
1299 this._actions = _actions;
1300 this._positionService = _positionService;
1301 this.valueChange = new EventEmitter();
1302 this.animationState = 'void';
1303 this._subs = [];
1304 this._effects = _effects;
1305 _renderer.setStyle(_element.nativeElement, 'display', 'block');
1306 _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
1307 }
1308 set value(value) {
1309 var _a;
1310 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setValue(value);
1311 }
1312 ngOnInit() {
1313 var _a, _b;
1314 this._positionService.setOptions({
1315 modifiers: { flip: { enabled: this._config.adaptivePosition } },
1316 allowedPositions: ['top', 'bottom']
1317 });
1318 (_a = this._positionService.event$) === null || _a === void 0 ? void 0 : _a.pipe(take(1)).subscribe(() => {
1319 this._positionService.disable();
1320 if (this._config.isAnimated) {
1321 this.animationState = this.isTopPosition ? 'animated-up' : 'animated-down';
1322 return;
1323 }
1324 this.animationState = 'unanimated';
1325 });
1326 this.isOtherMonthsActive = this._config.selectFromOtherMonth;
1327 this.containerClass = this._config.containerClass;
1328 this.showTodayBtn = this._config.showTodayButton;
1329 this.todayBtnLbl = this._config.todayButtonLabel;
1330 this.todayPos = this._config.todayPosition;
1331 this.showClearBtn = this._config.showClearButton;
1332 this.clearBtnLbl = this._config.clearButtonLabel;
1333 this.clearPos = this._config.clearPosition;
1334 this.customRangeBtnLbl = this._config.customRangeButtonLabel;
1335 (_b = this._effects) === null || _b === void 0 ? void 0 : _b.init(this._store).setOptions(this._config).setBindings(this).setEventHandlers(this).registerDatepickerSideEffects();
1336 // todo: move it somewhere else
1337 // on selected date change
1338 this._subs.push(this._store
1339 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1340 .select((state) => state.selectedDate)
1341 // eslint-disable-next-line @typescript-eslint/no-explicit-any
1342 .subscribe((date) => this.valueChange.emit(date)));
1343 this._store.dispatch(this._actions.changeViewMode(this._config.startView));
1344 }
1345 get isTopPosition() {
1346 return this._element.nativeElement.classList.contains('top');
1347 }
1348 positionServiceEnable() {
1349 this._positionService.enable();
1350 }
1351 daySelectHandler(day) {
1352 if (!day) {
1353 return;
1354 }
1355 const isDisabled = this.isOtherMonthsActive ? day.isDisabled : (day.isOtherMonth || day.isDisabled);
1356 if (isDisabled) {
1357 return;
1358 }
1359 this._store.dispatch(this._actions.select(day.date));
1360 }
1361 monthSelectHandler(day) {
1362 if (!day || day.isDisabled) {
1363 return;
1364 }
1365 this._store.dispatch(this._actions.navigateTo({
1366 unit: {
1367 month: getMonth(day.date),
1368 year: getFullYear(day.date)
1369 },
1370 viewMode: 'day'
1371 }));
1372 }
1373 yearSelectHandler(day) {
1374 if (!day || day.isDisabled) {
1375 return;
1376 }
1377 this._store.dispatch(this._actions.navigateTo({
1378 unit: {
1379 year: getFullYear(day.date)
1380 },
1381 viewMode: 'month'
1382 }));
1383 }
1384 setToday() {
1385 this._store.dispatch(this._actions.select(new Date()));
1386 }
1387 clearDate() {
1388 this._store.dispatch(this._actions.select(undefined));
1389 }
1390 ngOnDestroy() {
1391 var _a;
1392 for (const sub of this._subs) {
1393 sub.unsubscribe();
1394 }
1395 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.destroy();
1396 }
1397}
1398BsDatepickerContainerComponent.decorators = [
1399 { type: Component, args: [{
1400 selector: 'bs-datepicker-container',
1401 providers: [BsDatepickerStore, BsDatepickerEffects],
1402 template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n <div class=\"bs-datepicker-container\"\n [@datepickerAnimation]=\"animationState\"\n (@datepickerAnimation.done)=\"positionServiceEnable()\">\n <!--calendars-->\n <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n <!--days calendar-->\n <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n <bs-days-calendar-view\n *ngFor=\"let calendar of daysCalendar$ | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n [options]=\"options$ | async\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"dayHoverHandler($event)\"\n (onHoverWeek)=\"weekHoverHandler($event)\"\n (onSelect)=\"daySelectHandler($event)\">\n </bs-days-calendar-view>\n </div>\n\n <!--months calendar-->\n <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n <bs-month-calendar-view\n *ngFor=\"let calendar of monthsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"monthHoverHandler($event)\"\n (onSelect)=\"monthSelectHandler($event)\">\n </bs-month-calendar-view>\n </div>\n\n <!--years calendar-->\n <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n <bs-years-calendar-view\n *ngFor=\"let calendar of yearsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"yearHoverHandler($event)\"\n (onSelect)=\"yearSelectHandler($event)\">\n </bs-years-calendar-view>\n </div>\n </div>\n\n <!--applycancel buttons-->\n <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n <button class=\"btn btn-success\" type=\"button\">Apply</button>\n <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n </div>\n\n <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n <div class=\"btn-today-wrapper\"\n [class.today-left]=\"todayPos === 'left'\"\n [class.today-right]=\"todayPos === 'right'\"\n [class.today-center]=\"todayPos === 'center'\"\n *ngIf=\"showTodayBtn\">\n <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n </div>\n\n <div class=\"btn-clear-wrapper\"\n [class.clear-left]=\"clearPos === 'left'\"\n [class.clear-right]=\"clearPos === 'right'\"\n [class.clear-center]=\"clearPos === 'center'\"\n *ngIf=\"showClearBtn\">\n <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n </div>\n </div>\n\n </div>\n\n <!--custom dates or date ranges picker-->\n <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n <bs-custom-date-view\n [selectedRange]=\"chosenRange\"\n [ranges]=\"customRanges\"\n [customRangeLabel]=\"customRangeBtnLbl\"\n (onSelect)=\"setRangeOnCalendar($event)\">\n </bs-custom-date-view>\n </div>\n</div>\n",
1403 host: {
1404 class: 'bottom',
1405 '(click)': '_stopPropagation($event)',
1406 role: 'dialog',
1407 'aria-label': 'calendar'
1408 },
1409 animations: [datepickerAnimation]
1410 },] }
1411];
1412BsDatepickerContainerComponent.ctorParameters = () => [
1413 { type: Renderer2 },
1414 { type: BsDatepickerConfig },
1415 { type: BsDatepickerStore },
1416 { type: ElementRef },
1417 { type: BsDatepickerActions },
1418 { type: BsDatepickerEffects },
1419 { type: PositioningService }
1420];
1421
1422class BsDatepickerDirective {
1423 constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
1424 this._config = _config;
1425 this._elementRef = _elementRef;
1426 this._renderer = _renderer;
1427 /**
1428 * Placement of a datepicker. Accepts: "top", "bottom", "left", "right"
1429 */
1430 this.placement = 'bottom';
1431 /**
1432 * Specifies events that should trigger. Supports a space separated list of
1433 * event names.
1434 */
1435 this.triggers = 'click';
1436 /**
1437 * Close datepicker on outside click
1438 */
1439 this.outsideClick = true;
1440 /**
1441 * A selector specifying the element the datepicker should be appended to.
1442 */
1443 this.container = 'body';
1444 this.outsideEsc = true;
1445 this.isDestroy$ = new Subject();
1446 /**
1447 * Indicates whether datepicker's content is enabled or not
1448 */
1449 this.isDisabled = false;
1450 /**
1451 * Emits when datepicker value has been changed
1452 */
1453 this.bsValueChange = new EventEmitter();
1454 this._subs = [];
1455 this._dateInputFormat$ = new Subject();
1456 // todo: assign only subset of fields
1457 Object.assign(this, this._config);
1458 this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
1459 this.onShown = this._datepicker.onShown;
1460 this.onHidden = this._datepicker.onHidden;
1461 this.isOpen$ = new BehaviorSubject(this.isOpen);
1462 }
1463 /**
1464 * Returns whether or not the datepicker is currently being shown
1465 */
1466 get isOpen() {
1467 return this._datepicker.isShown;
1468 }
1469 set isOpen(value) {
1470 this.isOpen$.next(value);
1471 }
1472 /**
1473 * Initial value of datepicker
1474 */
1475 set bsValue(value) {
1476 if (this._bsValue && value && this._bsValue.getTime() === value.getTime()) {
1477 return;
1478 }
1479 if (!this._bsValue && value) {
1480 const now = new Date();
1481 value.setMilliseconds(now.getMilliseconds());
1482 value.setSeconds(now.getSeconds());
1483 value.setMinutes(now.getMinutes());
1484 value.setHours(now.getHours());
1485 }
1486 this._bsValue = value;
1487 this.bsValueChange.emit(value);
1488 }
1489 get dateInputFormat$() {
1490 return this._dateInputFormat$;
1491 }
1492 get bsConfig() {
1493 return this._bsConfig;
1494 }
1495 /**
1496 * Config object for datepicker
1497 */
1498 set bsConfig(bsConfig) {
1499 this._bsConfig = bsConfig;
1500 this.setConfig();
1501 this._dateInputFormat$.next(bsConfig && bsConfig.dateInputFormat);
1502 }
1503 ngOnInit() {
1504 this._datepicker.listen({
1505 outsideClick: this.outsideClick,
1506 outsideEsc: this.outsideEsc,
1507 triggers: this.triggers,
1508 show: () => this.show()
1509 });
1510 this.setConfig();
1511 }
1512 ngOnChanges(changes) {
1513 if (!this._datepickerRef || !this._datepickerRef.instance) {
1514 return;
1515 }
1516 if (changes.minDate) {
1517 this._datepickerRef.instance.minDate = this.minDate;
1518 }
1519 if (changes.maxDate) {
1520 this._datepickerRef.instance.maxDate = this.maxDate;
1521 }
1522 if (changes.daysDisabled) {
1523 this._datepickerRef.instance.daysDisabled = this.daysDisabled;
1524 }
1525 if (changes.datesDisabled) {
1526 this._datepickerRef.instance.datesDisabled = this.datesDisabled;
1527 }
1528 if (changes.datesEnabled) {
1529 this._datepickerRef.instance.datesEnabled = this.datesEnabled;
1530 }
1531 if (changes.isDisabled) {
1532 this._datepickerRef.instance.isDisabled = this.isDisabled;
1533 }
1534 if (changes.dateCustomClasses) {
1535 this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
1536 }
1537 if (changes.dateTooltipTexts) {
1538 this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
1539 }
1540 }
1541 ngAfterViewInit() {
1542 this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
1543 .subscribe(() => this.toggle());
1544 }
1545 /**
1546 * Opens an element’s datepicker. This is considered a “manual” triggering of
1547 * the datepicker.
1548 */
1549 show() {
1550 if (this._datepicker.isShown) {
1551 return;
1552 }
1553 this.setConfig();
1554 this._datepickerRef = this._datepicker
1555 .provide({ provide: BsDatepickerConfig, useValue: this._config })
1556 .attach(BsDatepickerContainerComponent)
1557 .to(this.container)
1558 .position({ attachment: this.placement })
1559 .show({ placement: this.placement });
1560 // if date changes from external source (model -> view)
1561 this._subs.push(this.bsValueChange.subscribe((value) => {
1562 if (this._datepickerRef) {
1563 this._datepickerRef.instance.value = value;
1564 }
1565 }));
1566 // if date changes from picker (view -> model)
1567 if (this._datepickerRef) {
1568 this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
1569 this.bsValue = value;
1570 this.hide();
1571 }));
1572 }
1573 }
1574 /**
1575 * Closes an element’s datepicker. This is considered a “manual” triggering of
1576 * the datepicker.
1577 */
1578 hide() {
1579 if (this.isOpen) {
1580 this._datepicker.hide();
1581 }
1582 for (const sub of this._subs) {
1583 sub.unsubscribe();
1584 }
1585 if (this._config.returnFocusToInput) {
1586 this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
1587 }
1588 }
1589 /**
1590 * Toggles an element’s datepicker. This is considered a “manual” triggering
1591 * of the datepicker.
1592 */
1593 toggle() {
1594 if (this.isOpen) {
1595 return this.hide();
1596 }
1597 this.show();
1598 }
1599 /**
1600 * Set config for datepicker
1601 */
1602 setConfig() {
1603 this._config = Object.assign({}, this._config, this.bsConfig, {
1604 value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
1605 isDisabled: this.isDisabled,
1606 minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
1607 maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
1608 daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
1609 dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
1610 dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
1611 datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
1612 datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
1613 minMode: this.minMode || this.bsConfig && this.bsConfig.minMode
1614 });
1615 }
1616 ngOnDestroy() {
1617 this._datepicker.dispose();
1618 this.isOpen$.next(false);
1619 if (this.isDestroy$) {
1620 this.isDestroy$.next();
1621 this.isDestroy$.complete();
1622 }
1623 }
1624}
1625BsDatepickerDirective.decorators = [
1626 { type: Directive, args: [{
1627 selector: '[bsDatepicker]',
1628 exportAs: 'bsDatepicker'
1629 },] }
1630];
1631BsDatepickerDirective.ctorParameters = () => [
1632 { type: BsDatepickerConfig },
1633 { type: ElementRef },
1634 { type: Renderer2 },
1635 { type: ViewContainerRef },
1636 { type: ComponentLoaderFactory }
1637];
1638BsDatepickerDirective.propDecorators = {
1639 placement: [{ type: Input }],
1640 triggers: [{ type: Input }],
1641 outsideClick: [{ type: Input }],
1642 container: [{ type: Input }],
1643 outsideEsc: [{ type: Input }],
1644 onShown: [{ type: Output }],
1645 onHidden: [{ type: Output }],
1646 isDisabled: [{ type: Input }],
1647 minDate: [{ type: Input }],
1648 maxDate: [{ type: Input }],
1649 minMode: [{ type: Input }],
1650 daysDisabled: [{ type: Input }],
1651 datesDisabled: [{ type: Input }],
1652 datesEnabled: [{ type: Input }],
1653 dateCustomClasses: [{ type: Input }],
1654 dateTooltipTexts: [{ type: Input }],
1655 bsValueChange: [{ type: Output }],
1656 isOpen: [{ type: Input }],
1657 bsValue: [{ type: Input }],
1658 bsConfig: [{ type: Input }]
1659};
1660
1661class BsDatepickerInlineConfig extends BsDatepickerConfig {
1662}
1663BsDatepickerInlineConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDatepickerInlineConfig_Factory() { return new BsDatepickerInlineConfig(); }, token: BsDatepickerInlineConfig, providedIn: "root" });
1664BsDatepickerInlineConfig.decorators = [
1665 { type: Injectable, args: [{
1666 providedIn: 'root'
1667 },] }
1668];
1669
1670class BsDatepickerInlineContainerComponent extends BsDatepickerContainerComponent {
1671 constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
1672 super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
1673 _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
1674 _renderer.setStyle(_element.nativeElement, 'position', 'static');
1675 }
1676}
1677BsDatepickerInlineContainerComponent.decorators = [
1678 { type: Component, args: [{
1679 selector: 'bs-datepicker-inline-container',
1680 providers: [BsDatepickerStore, BsDatepickerEffects],
1681 template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n <div class=\"bs-datepicker-container\"\n [@datepickerAnimation]=\"animationState\"\n (@datepickerAnimation.done)=\"positionServiceEnable()\">\n <!--calendars-->\n <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n <!--days calendar-->\n <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n <bs-days-calendar-view\n *ngFor=\"let calendar of daysCalendar$ | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n [options]=\"options$ | async\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"dayHoverHandler($event)\"\n (onHoverWeek)=\"weekHoverHandler($event)\"\n (onSelect)=\"daySelectHandler($event)\">\n </bs-days-calendar-view>\n </div>\n\n <!--months calendar-->\n <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n <bs-month-calendar-view\n *ngFor=\"let calendar of monthsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"monthHoverHandler($event)\"\n (onSelect)=\"monthSelectHandler($event)\">\n </bs-month-calendar-view>\n </div>\n\n <!--years calendar-->\n <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n <bs-years-calendar-view\n *ngFor=\"let calendar of yearsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"yearHoverHandler($event)\"\n (onSelect)=\"yearSelectHandler($event)\">\n </bs-years-calendar-view>\n </div>\n </div>\n\n <!--applycancel buttons-->\n <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n <button class=\"btn btn-success\" type=\"button\">Apply</button>\n <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n </div>\n\n <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n <div class=\"btn-today-wrapper\"\n [class.today-left]=\"todayPos === 'left'\"\n [class.today-right]=\"todayPos === 'right'\"\n [class.today-center]=\"todayPos === 'center'\"\n *ngIf=\"showTodayBtn\">\n <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n </div>\n\n <div class=\"btn-clear-wrapper\"\n [class.clear-left]=\"clearPos === 'left'\"\n [class.clear-right]=\"clearPos === 'right'\"\n [class.clear-center]=\"clearPos === 'center'\"\n *ngIf=\"showClearBtn\">\n <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n </div>\n </div>\n\n </div>\n\n <!--custom dates or date ranges picker-->\n <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n <bs-custom-date-view\n [selectedRange]=\"chosenRange\"\n [ranges]=\"customRanges\"\n [customRangeLabel]=\"customRangeBtnLbl\"\n (onSelect)=\"setRangeOnCalendar($event)\">\n </bs-custom-date-view>\n </div>\n</div>\n",
1682 host: {
1683 '(click)': '_stopPropagation($event)'
1684 },
1685 animations: [datepickerAnimation]
1686 },] }
1687];
1688BsDatepickerInlineContainerComponent.ctorParameters = () => [
1689 { type: Renderer2 },
1690 { type: BsDatepickerConfig },
1691 { type: BsDatepickerStore },
1692 { type: ElementRef },
1693 { type: BsDatepickerActions },
1694 { type: BsDatepickerEffects },
1695 { type: PositioningService }
1696];
1697
1698class BsDatepickerInlineDirective {
1699 constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
1700 this._config = _config;
1701 this._elementRef = _elementRef;
1702 /**
1703 * Indicates whether datepicker is enabled or not
1704 */
1705 this.isDisabled = false;
1706 /**
1707 * Emits when datepicker value has been changed
1708 */
1709 this.bsValueChange = new EventEmitter();
1710 this._subs = [];
1711 // todo: assign only subset of fields
1712 Object.assign(this, this._config);
1713 this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
1714 }
1715 /**
1716 * Initial value of datepicker
1717 */
1718 set bsValue(value) {
1719 if (this._bsValue === value) {
1720 return;
1721 }
1722 if (!this._bsValue && value) {
1723 const now = new Date();
1724 value.setMilliseconds(now.getMilliseconds());
1725 value.setSeconds(now.getSeconds());
1726 value.setMinutes(now.getMinutes());
1727 value.setHours(now.getHours());
1728 }
1729 this._bsValue = value;
1730 this.bsValueChange.emit(value);
1731 }
1732 ngOnInit() {
1733 this.setConfig();
1734 // if date changes from external source (model -> view)
1735 this._subs.push(this.bsValueChange.subscribe((value) => {
1736 if (this._datepickerRef) {
1737 this._datepickerRef.instance.value = value;
1738 }
1739 }));
1740 // if date changes from picker (view -> model)
1741 if (this._datepickerRef) {
1742 this._subs.push(this._datepickerRef.instance.valueChange.subscribe((value) => {
1743 this.bsValue = value;
1744 }));
1745 }
1746 }
1747 ngOnChanges(changes) {
1748 if (!this._datepickerRef || !this._datepickerRef.instance) {
1749 return;
1750 }
1751 if (changes.minDate) {
1752 this._datepickerRef.instance.minDate = this.minDate;
1753 this.setConfig();
1754 }
1755 if (changes.maxDate) {
1756 this._datepickerRef.instance.maxDate = this.maxDate;
1757 this.setConfig();
1758 }
1759 if (changes.datesDisabled) {
1760 this._datepickerRef.instance.datesDisabled = this.datesDisabled;
1761 this.setConfig();
1762 }
1763 if (changes.datesEnabled) {
1764 this._datepickerRef.instance.datesEnabled = this.datesEnabled;
1765 this._datepickerRef.instance.value = this._bsValue;
1766 }
1767 if (changes.isDisabled) {
1768 this._datepickerRef.instance.isDisabled = this.isDisabled;
1769 this.setConfig();
1770 }
1771 if (changes.dateCustomClasses) {
1772 this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
1773 this.setConfig();
1774 }
1775 if (changes.dateTooltipTexts) {
1776 this._datepickerRef.instance.dateTooltipTexts = this.dateTooltipTexts;
1777 this.setConfig();
1778 }
1779 }
1780 /**
1781 * Set config for datepicker
1782 */
1783 setConfig() {
1784 if (this._datepicker) {
1785 this._datepicker.hide();
1786 }
1787 this._config = Object.assign({}, this._config, this.bsConfig, {
1788 value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
1789 isDisabled: this.isDisabled,
1790 minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
1791 maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
1792 dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
1793 dateTooltipTexts: this.dateTooltipTexts || this.bsConfig && this.bsConfig.dateTooltipTexts,
1794 datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
1795 datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled
1796 });
1797 this._datepickerRef = this._datepicker
1798 .provide({ provide: BsDatepickerConfig, useValue: this._config })
1799 .attach(BsDatepickerInlineContainerComponent)
1800 .to(this._elementRef)
1801 .show();
1802 }
1803 ngOnDestroy() {
1804 this._datepicker.dispose();
1805 }
1806}
1807BsDatepickerInlineDirective.decorators = [
1808 { type: Directive, args: [{
1809 selector: 'bs-datepicker-inline',
1810 exportAs: 'bsDatepickerInline'
1811 },] }
1812];
1813BsDatepickerInlineDirective.ctorParameters = () => [
1814 { type: BsDatepickerInlineConfig },
1815 { type: ElementRef },
1816 { type: Renderer2 },
1817 { type: ViewContainerRef },
1818 { type: ComponentLoaderFactory }
1819];
1820BsDatepickerInlineDirective.propDecorators = {
1821 bsConfig: [{ type: Input }],
1822 isDisabled: [{ type: Input }],
1823 minDate: [{ type: Input }],
1824 maxDate: [{ type: Input }],
1825 dateCustomClasses: [{ type: Input }],
1826 dateTooltipTexts: [{ type: Input }],
1827 datesEnabled: [{ type: Input }],
1828 datesDisabled: [{ type: Input }],
1829 bsValueChange: [{ type: Output }],
1830 bsValue: [{ type: Input }]
1831};
1832
1833class BsDaterangepickerInlineConfig extends BsDatepickerConfig {
1834 constructor() {
1835 super(...arguments);
1836 // DatepickerRenderOptions
1837 this.displayMonths = 2;
1838 /** turn on/off animation */
1839 this.isAnimated = false;
1840 }
1841}
1842BsDaterangepickerInlineConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDaterangepickerInlineConfig_Factory() { return new BsDaterangepickerInlineConfig(); }, token: BsDaterangepickerInlineConfig, providedIn: "root" });
1843BsDaterangepickerInlineConfig.decorators = [
1844 { type: Injectable, args: [{
1845 providedIn: 'root'
1846 },] }
1847];
1848
1849class BsDaterangepickerContainerComponent extends BsDatepickerAbstractComponent {
1850 constructor(_renderer, _config, _store, _element, _actions, _effects, _positionService) {
1851 super();
1852 this._config = _config;
1853 this._store = _store;
1854 this._element = _element;
1855 this._actions = _actions;
1856 this._positionService = _positionService;
1857 this.valueChange = new EventEmitter();
1858 this.animationState = 'void';
1859 this._rangeStack = [];
1860 this.chosenRange = [];
1861 this._subs = [];
1862 this._effects = _effects;
1863 this.customRanges = this._config.ranges || [];
1864 this.customRangeBtnLbl = this._config.customRangeButtonLabel;
1865 _renderer.setStyle(_element.nativeElement, 'display', 'block');
1866 _renderer.setStyle(_element.nativeElement, 'position', 'absolute');
1867 }
1868 set value(value) {
1869 var _a;
1870 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setRangeValue(value);
1871 }
1872 ngOnInit() {
1873 var _a, _b;
1874 this._positionService.setOptions({
1875 modifiers: { flip: { enabled: this._config.adaptivePosition } },
1876 allowedPositions: ['top', 'bottom']
1877 });
1878 (_a = this._positionService.event$) === null || _a === void 0 ? void 0 : _a.pipe(take(1)).subscribe(() => {
1879 this._positionService.disable();
1880 if (this._config.isAnimated) {
1881 this.animationState = this.isTopPosition ? 'animated-up' : 'animated-down';
1882 return;
1883 }
1884 this.animationState = 'unanimated';
1885 });
1886 this.containerClass = this._config.containerClass;
1887 this.isOtherMonthsActive = this._config.selectFromOtherMonth;
1888 (_b = this._effects) === null || _b === void 0 ? void 0 : _b.init(this._store).setOptions(this._config).setBindings(this).setEventHandlers(this).registerDatepickerSideEffects();
1889 // todo: move it somewhere else
1890 // on selected date change
1891 this._subs.push(this._store
1892 .select(state => state.selectedRange)
1893 .subscribe(dateRange => {
1894 this.valueChange.emit(dateRange);
1895 this.chosenRange = dateRange || [];
1896 }));
1897 }
1898 get isTopPosition() {
1899 return this._element.nativeElement.classList.contains('top');
1900 }
1901 positionServiceEnable() {
1902 this._positionService.enable();
1903 }
1904 daySelectHandler(day) {
1905 if (!day) {
1906 return;
1907 }
1908 const isDisabled = this.isOtherMonthsActive ? day.isDisabled : (day.isOtherMonth || day.isDisabled);
1909 if (isDisabled) {
1910 return;
1911 }
1912 this.rangesProcessing(day);
1913 }
1914 monthSelectHandler(day) {
1915 if (!day || day.isDisabled) {
1916 return;
1917 }
1918 day.isSelected = true;
1919 if (this._config.minMode !== 'month') {
1920 if (day.isDisabled) {
1921 return;
1922 }
1923 this._store.dispatch(this._actions.navigateTo({
1924 unit: {
1925 month: getMonth(day.date),
1926 year: getFullYear(day.date)
1927 },
1928 viewMode: 'day'
1929 }));
1930 return;
1931 }
1932 this.rangesProcessing(day);
1933 }
1934 yearSelectHandler(day) {
1935 if (!day || day.isDisabled) {
1936 return;
1937 }
1938 day.isSelected = true;
1939 if (this._config.minMode !== 'year') {
1940 if (day.isDisabled) {
1941 return;
1942 }
1943 this._store.dispatch(this._actions.navigateTo({
1944 unit: {
1945 year: getFullYear(day.date)
1946 },
1947 viewMode: 'month'
1948 }));
1949 return;
1950 }
1951 this.rangesProcessing(day);
1952 }
1953 rangesProcessing(day) {
1954 // if only one date is already selected
1955 // and user clicks on previous date
1956 // start selection from new date
1957 // but if new date is after initial one
1958 // than finish selection
1959 if (this._rangeStack.length === 1) {
1960 this._rangeStack =
1961 day.date >= this._rangeStack[0]
1962 ? [this._rangeStack[0], day.date]
1963 : [day.date];
1964 }
1965 if (this._config.maxDateRange) {
1966 this.setMaxDateRangeOnCalendar(day.date);
1967 }
1968 if (this._rangeStack.length === 0) {
1969 this._rangeStack = [day.date];
1970 if (this._config.maxDateRange) {
1971 this.setMaxDateRangeOnCalendar(day.date);
1972 }
1973 }
1974 this._store.dispatch(this._actions.selectRange(this._rangeStack));
1975 if (this._rangeStack.length === 2) {
1976 this._rangeStack = [];
1977 }
1978 }
1979 ngOnDestroy() {
1980 var _a;
1981 for (const sub of this._subs) {
1982 sub.unsubscribe();
1983 }
1984 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.destroy();
1985 }
1986 setRangeOnCalendar(dates) {
1987 if (dates) {
1988 this._rangeStack = dates.value instanceof Date ? [dates.value] : dates.value;
1989 }
1990 this._store.dispatch(this._actions.selectRange(this._rangeStack));
1991 }
1992 setMaxDateRangeOnCalendar(currentSelection) {
1993 var _a;
1994 let maxDateRange = new Date(currentSelection);
1995 if (this._config.maxDate) {
1996 const maxDateValueInMilliseconds = this._config.maxDate.getTime();
1997 const maxDateRangeInMilliseconds = currentSelection.getTime() + ((this._config.maxDateRange || 0) * dayInMilliseconds);
1998 maxDateRange = maxDateRangeInMilliseconds > maxDateValueInMilliseconds ?
1999 new Date(this._config.maxDate) :
2000 new Date(maxDateRangeInMilliseconds);
2001 }
2002 else {
2003 maxDateRange.setDate(currentSelection.getDate() + (this._config.maxDateRange || 0));
2004 }
2005 (_a = this._effects) === null || _a === void 0 ? void 0 : _a.setMaxDate(maxDateRange);
2006 }
2007}
2008BsDaterangepickerContainerComponent.decorators = [
2009 { type: Component, args: [{
2010 selector: 'bs-daterangepicker-container',
2011 providers: [BsDatepickerStore, BsDatepickerEffects],
2012 template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n <div class=\"bs-datepicker-container\"\n [@datepickerAnimation]=\"animationState\"\n (@datepickerAnimation.done)=\"positionServiceEnable()\">\n <!--calendars-->\n <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n <!--days calendar-->\n <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n <bs-days-calendar-view\n *ngFor=\"let calendar of daysCalendar$ | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n [options]=\"options$ | async\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"dayHoverHandler($event)\"\n (onHoverWeek)=\"weekHoverHandler($event)\"\n (onSelect)=\"daySelectHandler($event)\">\n </bs-days-calendar-view>\n </div>\n\n <!--months calendar-->\n <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n <bs-month-calendar-view\n *ngFor=\"let calendar of monthsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"monthHoverHandler($event)\"\n (onSelect)=\"monthSelectHandler($event)\">\n </bs-month-calendar-view>\n </div>\n\n <!--years calendar-->\n <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n <bs-years-calendar-view\n *ngFor=\"let calendar of yearsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"yearHoverHandler($event)\"\n (onSelect)=\"yearSelectHandler($event)\">\n </bs-years-calendar-view>\n </div>\n </div>\n\n <!--applycancel buttons-->\n <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n <button class=\"btn btn-success\" type=\"button\">Apply</button>\n <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n </div>\n\n <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n <div class=\"btn-today-wrapper\"\n [class.today-left]=\"todayPos === 'left'\"\n [class.today-right]=\"todayPos === 'right'\"\n [class.today-center]=\"todayPos === 'center'\"\n *ngIf=\"showTodayBtn\">\n <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n </div>\n\n <div class=\"btn-clear-wrapper\"\n [class.clear-left]=\"clearPos === 'left'\"\n [class.clear-right]=\"clearPos === 'right'\"\n [class.clear-center]=\"clearPos === 'center'\"\n *ngIf=\"showClearBtn\">\n <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n </div>\n </div>\n\n </div>\n\n <!--custom dates or date ranges picker-->\n <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n <bs-custom-date-view\n [selectedRange]=\"chosenRange\"\n [ranges]=\"customRanges\"\n [customRangeLabel]=\"customRangeBtnLbl\"\n (onSelect)=\"setRangeOnCalendar($event)\">\n </bs-custom-date-view>\n </div>\n</div>\n",
2013 host: {
2014 class: 'bottom',
2015 '(click)': '_stopPropagation($event)',
2016 role: 'dialog',
2017 'aria-label': 'calendar'
2018 },
2019 animations: [datepickerAnimation]
2020 },] }
2021];
2022BsDaterangepickerContainerComponent.ctorParameters = () => [
2023 { type: Renderer2 },
2024 { type: BsDatepickerConfig },
2025 { type: BsDatepickerStore },
2026 { type: ElementRef },
2027 { type: BsDatepickerActions },
2028 { type: BsDatepickerEffects },
2029 { type: PositioningService }
2030];
2031
2032class BsDaterangepickerInlineContainerComponent extends BsDaterangepickerContainerComponent {
2033 constructor(_renderer, _config, _store, _element, _actions, _effects, _positioningService) {
2034 super(_renderer, _config, _store, _element, _actions, _effects, _positioningService);
2035 _renderer.setStyle(_element.nativeElement, 'display', 'inline-block');
2036 _renderer.setStyle(_element.nativeElement, 'position', 'static');
2037 }
2038}
2039BsDaterangepickerInlineContainerComponent.decorators = [
2040 { type: Component, args: [{
2041 selector: 'bs-daterangepicker-inline-container',
2042 providers: [BsDatepickerStore, BsDatepickerEffects],
2043 template: "<!-- days calendar view mode -->\n<div class=\"bs-datepicker\" [ngClass]=\"containerClass\" *ngIf=\"viewMode | async\">\n <div class=\"bs-datepicker-container\"\n [@datepickerAnimation]=\"animationState\"\n (@datepickerAnimation.done)=\"positionServiceEnable()\">\n <!--calendars-->\n <div class=\"bs-calendar-container\" [ngSwitch]=\"viewMode | async\" role=\"application\">\n <!--days calendar-->\n <div *ngSwitchCase=\"'day'\" class=\"bs-media-container\">\n <bs-days-calendar-view\n *ngFor=\"let calendar of daysCalendar$ | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n [options]=\"options$ | async\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"dayHoverHandler($event)\"\n (onHoverWeek)=\"weekHoverHandler($event)\"\n (onSelect)=\"daySelectHandler($event)\">\n </bs-days-calendar-view>\n </div>\n\n <!--months calendar-->\n <div *ngSwitchCase=\"'month'\" class=\"bs-media-container\">\n <bs-month-calendar-view\n *ngFor=\"let calendar of monthsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"monthHoverHandler($event)\"\n (onSelect)=\"monthSelectHandler($event)\">\n </bs-month-calendar-view>\n </div>\n\n <!--years calendar-->\n <div *ngSwitchCase=\"'year'\" class=\"bs-media-container\">\n <bs-years-calendar-view\n *ngFor=\"let calendar of yearsCalendar | async\"\n [class.bs-datepicker-multiple]=\"multipleCalendars\"\n [calendar]=\"calendar\"\n (onNavigate)=\"navigateTo($event)\"\n (onViewMode)=\"setViewMode($event)\"\n (onHover)=\"yearHoverHandler($event)\"\n (onSelect)=\"yearSelectHandler($event)\">\n </bs-years-calendar-view>\n </div>\n </div>\n\n <!--applycancel buttons-->\n <div class=\"bs-datepicker-buttons\" *ngIf=\"false\">\n <button class=\"btn btn-success\" type=\"button\">Apply</button>\n <button class=\"btn btn-default\" type=\"button\">Cancel</button>\n </div>\n\n <div class=\"bs-datepicker-buttons\" *ngIf=\"showTodayBtn || showClearBtn\">\n <div class=\"btn-today-wrapper\"\n [class.today-left]=\"todayPos === 'left'\"\n [class.today-right]=\"todayPos === 'right'\"\n [class.today-center]=\"todayPos === 'center'\"\n *ngIf=\"showTodayBtn\">\n <button class=\"btn btn-success\" (click)=\"setToday()\">{{todayBtnLbl}}</button>\n </div>\n\n <div class=\"btn-clear-wrapper\"\n [class.clear-left]=\"clearPos === 'left'\"\n [class.clear-right]=\"clearPos === 'right'\"\n [class.clear-center]=\"clearPos === 'center'\"\n *ngIf=\"showClearBtn\">\n <button class=\"btn btn-success\" (click)=\"clearDate()\">{{clearBtnLbl}}</button>\n </div>\n </div>\n\n </div>\n\n <!--custom dates or date ranges picker-->\n <div class=\"bs-datepicker-custom-range\" *ngIf=\"customRanges && customRanges.length > 0\">\n <bs-custom-date-view\n [selectedRange]=\"chosenRange\"\n [ranges]=\"customRanges\"\n [customRangeLabel]=\"customRangeBtnLbl\"\n (onSelect)=\"setRangeOnCalendar($event)\">\n </bs-custom-date-view>\n </div>\n</div>\n",
2044 host: {
2045 '(click)': '_stopPropagation($event)'
2046 },
2047 animations: [datepickerAnimation]
2048 },] }
2049];
2050BsDaterangepickerInlineContainerComponent.ctorParameters = () => [
2051 { type: Renderer2 },
2052 { type: BsDatepickerConfig },
2053 { type: BsDatepickerStore },
2054 { type: ElementRef },
2055 { type: BsDatepickerActions },
2056 { type: BsDatepickerEffects },
2057 { type: PositioningService }
2058];
2059
2060class BsDaterangepickerInlineDirective {
2061 constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
2062 this._config = _config;
2063 this._elementRef = _elementRef;
2064 /**
2065 * Indicates whether datepicker is enabled or not
2066 */
2067 this.isDisabled = false;
2068 /**
2069 * Emits when daterangepicker value has been changed
2070 */
2071 this.bsValueChange = new EventEmitter();
2072 this._subs = [];
2073 // todo: assign only subset of fields
2074 Object.assign(this, this._config);
2075 this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
2076 }
2077 /**
2078 * Initial value of datepicker
2079 */
2080 set bsValue(value) {
2081 if (this._bsValue === value) {
2082 return;
2083 }
2084 this._bsValue = value;
2085 this.bsValueChange.emit(value);
2086 }
2087 ngOnInit() {
2088 this.setConfig();
2089 // if date changes from external source (model -> view)
2090 this._subs.push(this.bsValueChange.subscribe((value) => {
2091 if (this._datepickerRef) {
2092 this._datepickerRef.instance.value = value;
2093 }
2094 }));
2095 // if date changes from picker (view -> model)
2096 if (this._datepickerRef) {
2097 this._subs.push(this._datepickerRef.instance.valueChange
2098 .pipe(filter((range) => range && range[0] && !!range[1]))
2099 .subscribe((value) => {
2100 this.bsValue = value;
2101 }));
2102 }
2103 }
2104 ngOnChanges(changes) {
2105 if (!this._datepickerRef || !this._datepickerRef.instance) {
2106 return;
2107 }
2108 if (changes.minDate) {
2109 this._datepickerRef.instance.minDate = this.minDate;
2110 this.setConfig();
2111 }
2112 if (changes.maxDate) {
2113 this._datepickerRef.instance.maxDate = this.maxDate;
2114 this.setConfig();
2115 }
2116 if (changes.datesEnabled) {
2117 this._datepickerRef.instance.datesEnabled = this.datesEnabled;
2118 }
2119 if (changes.datesDisabled) {
2120 this._datepickerRef.instance.datesDisabled = this.datesDisabled;
2121 this.setConfig();
2122 }
2123 if (changes.daysDisabled) {
2124 this._datepickerRef.instance.daysDisabled = this.daysDisabled;
2125 this.setConfig();
2126 }
2127 if (changes.isDisabled) {
2128 this._datepickerRef.instance.isDisabled = this.isDisabled;
2129 this.setConfig();
2130 }
2131 if (changes.dateCustomClasses) {
2132 this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
2133 this.setConfig();
2134 }
2135 }
2136 /**
2137 * Set config for datepicker
2138 */
2139 setConfig() {
2140 if (this._datepicker) {
2141 this._datepicker.hide();
2142 }
2143 this._config = Object.assign({}, this._config, this.bsConfig, {
2144 value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
2145 isDisabled: this.isDisabled,
2146 minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
2147 maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
2148 daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
2149 dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
2150 datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
2151 datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
2152 ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
2153 maxDateRange: this.bsConfig && this.bsConfig.maxDateRange
2154 });
2155 this._datepickerRef = this._datepicker
2156 .provide({ provide: BsDatepickerConfig, useValue: this._config })
2157 .attach(BsDaterangepickerInlineContainerComponent)
2158 .to(this._elementRef)
2159 .show();
2160 }
2161 ngOnDestroy() {
2162 this._datepicker.dispose();
2163 }
2164}
2165BsDaterangepickerInlineDirective.decorators = [
2166 { type: Directive, args: [{
2167 selector: 'bs-daterangepicker-inline',
2168 exportAs: 'bsDaterangepickerInline'
2169 },] }
2170];
2171BsDaterangepickerInlineDirective.ctorParameters = () => [
2172 { type: BsDaterangepickerInlineConfig },
2173 { type: ElementRef },
2174 { type: Renderer2 },
2175 { type: ViewContainerRef },
2176 { type: ComponentLoaderFactory }
2177];
2178BsDaterangepickerInlineDirective.propDecorators = {
2179 bsValue: [{ type: Input }],
2180 bsConfig: [{ type: Input }],
2181 isDisabled: [{ type: Input }],
2182 minDate: [{ type: Input }],
2183 maxDate: [{ type: Input }],
2184 dateCustomClasses: [{ type: Input }],
2185 daysDisabled: [{ type: Input }],
2186 datesDisabled: [{ type: Input }],
2187 datesEnabled: [{ type: Input }],
2188 bsValueChange: [{ type: Output }]
2189};
2190
2191const BS_DATEPICKER_VALUE_ACCESSOR = {
2192 provide: NG_VALUE_ACCESSOR,
2193 useExisting: forwardRef(() => BsDatepickerInputDirective),
2194 multi: true
2195};
2196const BS_DATEPICKER_VALIDATOR = {
2197 provide: NG_VALIDATORS,
2198 useExisting: forwardRef(() => BsDatepickerInputDirective),
2199 multi: true
2200};
2201class BsDatepickerInputDirective {
2202 constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
2203 this._picker = _picker;
2204 this._localeService = _localeService;
2205 this._renderer = _renderer;
2206 this._elRef = _elRef;
2207 this.changeDetection = changeDetection;
2208 this._onChange = Function.prototype;
2209 this._onTouched = Function.prototype;
2210 this._validatorChange = Function.prototype;
2211 this._subs = new Subscription();
2212 }
2213 ngOnInit() {
2214 const setBsValue = (value) => {
2215 this._setInputValue(value);
2216 if (this._value !== value) {
2217 this._value = value;
2218 this._onChange(value);
2219 this._onTouched();
2220 }
2221 this.changeDetection.markForCheck();
2222 };
2223 // if value set via [bsValue] it will not get into value change
2224 if (this._picker._bsValue) {
2225 setBsValue(this._picker._bsValue);
2226 }
2227 // update input value on datepicker value update
2228 this._subs.add(this._picker.bsValueChange.subscribe(setBsValue));
2229 // update input value on locale change
2230 this._subs.add(this._localeService.localeChange.subscribe(() => {
2231 this._setInputValue(this._value);
2232 }));
2233 this._subs.add(this._picker.dateInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
2234 this._setInputValue(this._value);
2235 }));
2236 }
2237 ngOnDestroy() {
2238 this._subs.unsubscribe();
2239 }
2240 onKeydownEvent(event) {
2241 if (event.keyCode === 13 || event.code === 'Enter') {
2242 this.hide();
2243 }
2244 }
2245 _setInputValue(value) {
2246 const initialDate = !value ? ''
2247 : formatDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
2248 this._renderer.setProperty(this._elRef.nativeElement, 'value', initialDate);
2249 }
2250 onChange(event) {
2251 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2252 this.writeValue(event.target.value);
2253 this._onChange(this._value);
2254 if (this._picker._config.returnFocusToInput) {
2255 this._renderer.selectRootElement(this._elRef.nativeElement).focus();
2256 }
2257 this._onTouched();
2258 }
2259 validate(c) {
2260 const _value = c.value;
2261 if (_value === null || _value === undefined || _value === '') {
2262 return null;
2263 }
2264 if (isDate(_value)) {
2265 const _isDateValid = isDateValid(_value);
2266 if (!_isDateValid) {
2267 return { bsDate: { invalid: _value } };
2268 }
2269 if (this._picker && this._picker.minDate && isBefore(_value, this._picker.minDate, 'date')) {
2270 this.writeValue(this._picker.minDate);
2271 return { bsDate: { minDate: this._picker.minDate } };
2272 }
2273 if (this._picker && this._picker.maxDate && isAfter(_value, this._picker.maxDate, 'date')) {
2274 this.writeValue(this._picker.maxDate);
2275 return { bsDate: { maxDate: this._picker.maxDate } };
2276 }
2277 }
2278 return null;
2279 }
2280 registerOnValidatorChange(fn) {
2281 this._validatorChange = fn;
2282 }
2283 writeValue(value) {
2284 if (!value) {
2285 this._value = void 0;
2286 }
2287 else {
2288 const _localeKey = this._localeService.currentLocale;
2289 const _locale = getLocale(_localeKey);
2290 if (!_locale) {
2291 throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
2292 }
2293 this._value = parseDate(value, this._picker._config.dateInputFormat, this._localeService.currentLocale);
2294 if (this._picker._config.useUtc) {
2295 this._value = utcAsLocal(this._value);
2296 }
2297 }
2298 this._picker.bsValue = this._value;
2299 }
2300 setDisabledState(isDisabled) {
2301 this._picker.isDisabled = isDisabled;
2302 if (isDisabled) {
2303 this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
2304 return;
2305 }
2306 this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
2307 }
2308 registerOnChange(fn) {
2309 this._onChange = fn;
2310 }
2311 registerOnTouched(fn) {
2312 this._onTouched = fn;
2313 }
2314 onBlur() {
2315 this._onTouched();
2316 }
2317 hide() {
2318 this._picker.hide();
2319 this._renderer.selectRootElement(this._elRef.nativeElement).blur();
2320 if (this._picker._config.returnFocusToInput) {
2321 this._renderer.selectRootElement(this._elRef.nativeElement).focus();
2322 }
2323 }
2324}
2325BsDatepickerInputDirective.decorators = [
2326 { type: Directive, args: [{
2327 selector: `input[bsDatepicker]`,
2328 // eslint-disable-next-line @angular-eslint/no-host-metadata-property
2329 host: {
2330 '(change)': 'onChange($event)',
2331 '(keyup.esc)': 'hide()',
2332 '(keydown)': 'onKeydownEvent($event)',
2333 '(blur)': 'onBlur()'
2334 },
2335 providers: [BS_DATEPICKER_VALUE_ACCESSOR, BS_DATEPICKER_VALIDATOR]
2336 },] }
2337];
2338BsDatepickerInputDirective.ctorParameters = () => [
2339 { type: BsDatepickerDirective, decorators: [{ type: Host }] },
2340 { type: BsLocaleService },
2341 { type: Renderer2 },
2342 { type: ElementRef },
2343 { type: ChangeDetectorRef }
2344];
2345
2346class BsDaterangepickerConfig extends BsDatepickerConfig {
2347 constructor() {
2348 super(...arguments);
2349 // DatepickerRenderOptions
2350 this.displayMonths = 2;
2351 }
2352}
2353BsDaterangepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function BsDaterangepickerConfig_Factory() { return new BsDaterangepickerConfig(); }, token: BsDaterangepickerConfig, providedIn: "root" });
2354BsDaterangepickerConfig.decorators = [
2355 { type: Injectable, args: [{
2356 providedIn: 'root'
2357 },] }
2358];
2359
2360class BsDaterangepickerDirective {
2361 constructor(_config, _elementRef, _renderer, _viewContainerRef, cis) {
2362 this._config = _config;
2363 this._elementRef = _elementRef;
2364 this._renderer = _renderer;
2365 /**
2366 * Placement of a daterangepicker. Accepts: "top", "bottom", "left", "right"
2367 */
2368 this.placement = 'bottom';
2369 /**
2370 * Specifies events that should trigger. Supports a space separated list of
2371 * event names.
2372 */
2373 this.triggers = 'click';
2374 /**
2375 * Close daterangepicker on outside click
2376 */
2377 this.outsideClick = true;
2378 /**
2379 * A selector specifying the element the daterangepicker should be appended to.
2380 */
2381 this.container = 'body';
2382 this.outsideEsc = true;
2383 this.isDestroy$ = new Subject();
2384 /**
2385 * Indicates whether daterangepicker's content is enabled or not
2386 */
2387 this.isDisabled = false;
2388 /**
2389 * Emits when daterangepicker value has been changed
2390 */
2391 this.bsValueChange = new EventEmitter();
2392 this._subs = [];
2393 this._rangeInputFormat$ = new Subject();
2394 this._datepicker = cis.createLoader(_elementRef, _viewContainerRef, _renderer);
2395 Object.assign(this, _config);
2396 this.onShown = this._datepicker.onShown;
2397 this.onHidden = this._datepicker.onHidden;
2398 this.isOpen$ = new BehaviorSubject(this.isOpen);
2399 }
2400 /**
2401 * Returns whether or not the daterangepicker is currently being shown
2402 */
2403 get isOpen() {
2404 return this._datepicker.isShown;
2405 }
2406 set isOpen(value) {
2407 this.isOpen$.next(value);
2408 }
2409 /**
2410 * Initial value of daterangepicker
2411 */
2412 set bsValue(value) {
2413 if (this._bsValue === value) {
2414 return;
2415 }
2416 this._bsValue = value;
2417 this.bsValueChange.emit(value);
2418 }
2419 /**
2420 * Config object for daterangepicker
2421 */
2422 set bsConfig(bsConfig) {
2423 this._bsConfig = bsConfig;
2424 this.setConfig();
2425 this._rangeInputFormat$.next(bsConfig && bsConfig.rangeInputFormat);
2426 }
2427 get bsConfig() {
2428 return this._bsConfig;
2429 }
2430 get rangeInputFormat$() {
2431 return this._rangeInputFormat$;
2432 }
2433 ngOnInit() {
2434 this.isDestroy$ = new Subject();
2435 this._datepicker.listen({
2436 outsideClick: this.outsideClick,
2437 outsideEsc: this.outsideEsc,
2438 triggers: this.triggers,
2439 show: () => this.show()
2440 });
2441 this.setConfig();
2442 }
2443 ngOnChanges(changes) {
2444 if (!this._datepickerRef || !this._datepickerRef.instance) {
2445 return;
2446 }
2447 if (changes.minDate) {
2448 this._datepickerRef.instance.minDate = this.minDate;
2449 }
2450 if (changes.maxDate) {
2451 this._datepickerRef.instance.maxDate = this.maxDate;
2452 }
2453 if (changes.datesDisabled) {
2454 this._datepickerRef.instance.datesDisabled = this.datesDisabled;
2455 }
2456 if (changes.datesEnabled) {
2457 this._datepickerRef.instance.datesEnabled = this.datesEnabled;
2458 }
2459 if (changes.daysDisabled) {
2460 this._datepickerRef.instance.daysDisabled = this.daysDisabled;
2461 }
2462 if (changes.isDisabled) {
2463 this._datepickerRef.instance.isDisabled = this.isDisabled;
2464 }
2465 if (changes.dateCustomClasses) {
2466 this._datepickerRef.instance.dateCustomClasses = this.dateCustomClasses;
2467 }
2468 }
2469 ngAfterViewInit() {
2470 this.isOpen$.pipe(filter(isOpen => isOpen !== this.isOpen), takeUntil(this.isDestroy$))
2471 .subscribe(() => this.toggle());
2472 }
2473 /**
2474 * Opens an element’s datepicker. This is considered a “manual” triggering of
2475 * the datepicker.
2476 */
2477 show() {
2478 if (this._datepicker.isShown) {
2479 return;
2480 }
2481 this.setConfig();
2482 this._datepickerRef = this._datepicker
2483 .provide({ provide: BsDatepickerConfig, useValue: this._config })
2484 .attach(BsDaterangepickerContainerComponent)
2485 .to(this.container)
2486 .position({ attachment: this.placement })
2487 .show({ placement: this.placement });
2488 // if date changes from external source (model -> view)
2489 this._subs.push(this.bsValueChange.subscribe((value) => {
2490 if (this._datepickerRef) {
2491 this._datepickerRef.instance.value = value;
2492 }
2493 }));
2494 // if date changes from picker (view -> model)
2495 if (this._datepickerRef) {
2496 this._subs.push(this._datepickerRef.instance.valueChange
2497 .pipe(filter((range) => range && range[0] && !!range[1]))
2498 .subscribe((value) => {
2499 this.bsValue = value;
2500 this.hide();
2501 }));
2502 }
2503 }
2504 /**
2505 * Set config for daterangepicker
2506 */
2507 setConfig() {
2508 this._config = Object.assign({}, this._config, this.bsConfig, {
2509 value: checkBsValue(this._bsValue, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
2510 isDisabled: this.isDisabled,
2511 minDate: this.minDate || this.bsConfig && this.bsConfig.minDate,
2512 maxDate: this.maxDate || this.bsConfig && this.bsConfig.maxDate,
2513 daysDisabled: this.daysDisabled || this.bsConfig && this.bsConfig.daysDisabled,
2514 dateCustomClasses: this.dateCustomClasses || this.bsConfig && this.bsConfig.dateCustomClasses,
2515 datesDisabled: this.datesDisabled || this.bsConfig && this.bsConfig.datesDisabled,
2516 datesEnabled: this.datesEnabled || this.bsConfig && this.bsConfig.datesEnabled,
2517 ranges: checkRangesWithMaxDate(this.bsConfig && this.bsConfig.ranges, this.maxDate || this.bsConfig && this.bsConfig.maxDate),
2518 maxDateRange: this.bsConfig && this.bsConfig.maxDateRange
2519 });
2520 }
2521 /**
2522 * Closes an element’s datepicker. This is considered a “manual” triggering of
2523 * the datepicker.
2524 */
2525 hide() {
2526 if (this.isOpen) {
2527 this._datepicker.hide();
2528 }
2529 for (const sub of this._subs) {
2530 sub.unsubscribe();
2531 }
2532 if (this._config.returnFocusToInput) {
2533 this._renderer.selectRootElement(this._elementRef.nativeElement).focus();
2534 }
2535 }
2536 /**
2537 * Toggles an element’s datepicker. This is considered a “manual” triggering
2538 * of the datepicker.
2539 */
2540 toggle() {
2541 if (this.isOpen) {
2542 return this.hide();
2543 }
2544 this.show();
2545 }
2546 ngOnDestroy() {
2547 this._datepicker.dispose();
2548 this.isOpen$.next(false);
2549 if (this.isDestroy$) {
2550 this.isDestroy$.next();
2551 this.isDestroy$.complete();
2552 }
2553 }
2554}
2555BsDaterangepickerDirective.decorators = [
2556 { type: Directive, args: [{
2557 selector: '[bsDaterangepicker]',
2558 exportAs: 'bsDaterangepicker'
2559 },] }
2560];
2561BsDaterangepickerDirective.ctorParameters = () => [
2562 { type: BsDaterangepickerConfig },
2563 { type: ElementRef },
2564 { type: Renderer2 },
2565 { type: ViewContainerRef },
2566 { type: ComponentLoaderFactory }
2567];
2568BsDaterangepickerDirective.propDecorators = {
2569 placement: [{ type: Input }],
2570 triggers: [{ type: Input }],
2571 outsideClick: [{ type: Input }],
2572 container: [{ type: Input }],
2573 outsideEsc: [{ type: Input }],
2574 isOpen: [{ type: Input }],
2575 onShown: [{ type: Output }],
2576 onHidden: [{ type: Output }],
2577 bsValue: [{ type: Input }],
2578 bsConfig: [{ type: Input }],
2579 isDisabled: [{ type: Input }],
2580 minDate: [{ type: Input }],
2581 maxDate: [{ type: Input }],
2582 dateCustomClasses: [{ type: Input }],
2583 daysDisabled: [{ type: Input }],
2584 datesDisabled: [{ type: Input }],
2585 datesEnabled: [{ type: Input }],
2586 bsValueChange: [{ type: Output }]
2587};
2588
2589const BS_DATERANGEPICKER_VALUE_ACCESSOR = {
2590 provide: NG_VALUE_ACCESSOR,
2591 useExisting: forwardRef(() => BsDaterangepickerInputDirective),
2592 multi: true
2593};
2594const BS_DATERANGEPICKER_VALIDATOR = {
2595 provide: NG_VALIDATORS,
2596 useExisting: forwardRef(() => BsDaterangepickerInputDirective),
2597 multi: true
2598};
2599class BsDaterangepickerInputDirective {
2600 constructor(_picker, _localeService, _renderer, _elRef, changeDetection) {
2601 this._picker = _picker;
2602 this._localeService = _localeService;
2603 this._renderer = _renderer;
2604 this._elRef = _elRef;
2605 this.changeDetection = changeDetection;
2606 this._onChange = Function.prototype;
2607 this._onTouched = Function.prototype;
2608 this._validatorChange = Function.prototype;
2609 this._subs = new Subscription();
2610 }
2611 ngOnInit() {
2612 const setBsValue = (value) => {
2613 this._setInputValue(value);
2614 if (this._value !== value) {
2615 this._value = value;
2616 this._onChange(value);
2617 this._onTouched();
2618 }
2619 this.changeDetection.markForCheck();
2620 };
2621 // if value set via [bsValue] it will not get into value change
2622 if (this._picker._bsValue) {
2623 setBsValue(this._picker._bsValue);
2624 }
2625 // update input value on datepicker value update
2626 this._subs.add(this._picker.bsValueChange.subscribe((value) => {
2627 this._setInputValue(value);
2628 if (this._value !== value) {
2629 this._value = value;
2630 this._onChange(value);
2631 this._onTouched();
2632 }
2633 this.changeDetection.markForCheck();
2634 }));
2635 // update input value on locale change
2636 this._subs.add(this._localeService.localeChange.subscribe(() => {
2637 this._setInputValue(this._value);
2638 }));
2639 this._subs.add(
2640 // update input value on format change
2641 this._picker.rangeInputFormat$.pipe(distinctUntilChanged()).subscribe(() => {
2642 this._setInputValue(this._value);
2643 }));
2644 }
2645 ngOnDestroy() {
2646 this._subs.unsubscribe();
2647 }
2648 onKeydownEvent(event) {
2649 if (event.keyCode === 13 || event.code === 'Enter') {
2650 this.hide();
2651 }
2652 }
2653 _setInputValue(date) {
2654 let range = '';
2655 if (date) {
2656 const start = !date[0] ? ''
2657 : formatDate(date[0], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
2658 const end = !date[1] ? ''
2659 : formatDate(date[1], this._picker._config.rangeInputFormat, this._localeService.currentLocale);
2660 range = (start && end) ? start + this._picker._config.rangeSeparator + end : '';
2661 }
2662 this._renderer.setProperty(this._elRef.nativeElement, 'value', range);
2663 }
2664 onChange(event) {
2665 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2666 this.writeValue(event.target.value);
2667 this._onChange(this._value);
2668 if (this._picker._config.returnFocusToInput) {
2669 this._renderer.selectRootElement(this._elRef.nativeElement).focus();
2670 }
2671 this._onTouched();
2672 }
2673 validate(c) {
2674 let _value = c.value;
2675 const errors = [];
2676 if (_value === null || _value === undefined || !isArray(_value)) {
2677 return null;
2678 }
2679 _value = _value.slice().sort((a, b) => a.getTime() - b.getTime());
2680 const _isFirstDateValid = isDateValid(_value[0]);
2681 const _isSecondDateValid = isDateValid(_value[1]);
2682 if (!_isFirstDateValid) {
2683 return { bsDate: { invalid: _value[0] } };
2684 }
2685 if (!_isSecondDateValid) {
2686 return { bsDate: { invalid: _value[1] } };
2687 }
2688 if (this._picker && this._picker.minDate && isBefore(_value[0], this._picker.minDate, 'date')) {
2689 _value[0] = this._picker.minDate;
2690 errors.push({ bsDate: { minDate: this._picker.minDate } });
2691 }
2692 if (this._picker && this._picker.maxDate && isAfter(_value[1], this._picker.maxDate, 'date')) {
2693 _value[1] = this._picker.maxDate;
2694 errors.push({ bsDate: { maxDate: this._picker.maxDate } });
2695 }
2696 if (errors.length > 0) {
2697 this.writeValue(_value);
2698 return errors;
2699 }
2700 return null;
2701 }
2702 registerOnValidatorChange(fn) {
2703 this._validatorChange = fn;
2704 }
2705 writeValue(value) {
2706 if (!value) {
2707 this._value = void 0;
2708 }
2709 else {
2710 const _localeKey = this._localeService.currentLocale;
2711 const _locale = getLocale(_localeKey);
2712 if (!_locale) {
2713 throw new Error(`Locale "${_localeKey}" is not defined, please add it with "defineLocale(...)"`);
2714 }
2715 let _input = [];
2716 if (typeof value === 'string') {
2717 const trimmedSeparator = this._picker._config.rangeSeparator.trim();
2718 _input = value
2719 .split(trimmedSeparator.length > 0 ? trimmedSeparator : this._picker._config.rangeSeparator)
2720 .map(_val => _val.trim());
2721 }
2722 if (Array.isArray(value)) {
2723 _input = value;
2724 }
2725 this._value = _input
2726 .map((_val) => {
2727 if (this._picker._config.useUtc) {
2728 return utcAsLocal(parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale));
2729 }
2730 return parseDate(_val, this._picker._config.rangeInputFormat, this._localeService.currentLocale);
2731 })
2732 .map((date) => (isNaN(date.valueOf()) ? void 0 : date));
2733 }
2734 this._picker.bsValue = this._value;
2735 }
2736 setDisabledState(isDisabled) {
2737 this._picker.isDisabled = isDisabled;
2738 if (isDisabled) {
2739 this._renderer.setAttribute(this._elRef.nativeElement, 'disabled', 'disabled');
2740 return;
2741 }
2742 this._renderer.removeAttribute(this._elRef.nativeElement, 'disabled');
2743 }
2744 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2745 registerOnChange(fn) {
2746 this._onChange = fn;
2747 }
2748 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2749 registerOnTouched(fn) {
2750 this._onTouched = fn;
2751 }
2752 onBlur() {
2753 this._onTouched();
2754 }
2755 hide() {
2756 this._picker.hide();
2757 this._renderer.selectRootElement(this._elRef.nativeElement).blur();
2758 if (this._picker._config.returnFocusToInput) {
2759 this._renderer.selectRootElement(this._elRef.nativeElement).focus();
2760 }
2761 }
2762}
2763BsDaterangepickerInputDirective.decorators = [
2764 { type: Directive, args: [{
2765 selector: `input[bsDaterangepicker]`,
2766 // eslint-disable-next-line @angular-eslint/no-host-metadata-property
2767 host: {
2768 '(change)': 'onChange($event)',
2769 '(keyup.esc)': 'hide()',
2770 '(keydown)': 'onKeydownEvent($event)',
2771 '(blur)': 'onBlur()'
2772 },
2773 providers: [BS_DATERANGEPICKER_VALUE_ACCESSOR, BS_DATERANGEPICKER_VALIDATOR]
2774 },] }
2775];
2776BsDaterangepickerInputDirective.ctorParameters = () => [
2777 { type: BsDaterangepickerDirective, decorators: [{ type: Host }] },
2778 { type: BsLocaleService },
2779 { type: Renderer2 },
2780 { type: ElementRef },
2781 { type: ChangeDetectorRef }
2782];
2783
2784class DateFormatter {
2785 format(date, format, locale) {
2786 return formatDate(date, format, locale);
2787 }
2788}
2789
2790class DatePickerInnerComponent {
2791 constructor() {
2792 this.monthColLimit = 0;
2793 this.yearColLimit = 0;
2794 this.selectionDone = new EventEmitter(undefined);
2795 this.update = new EventEmitter(false);
2796 this.activeDateChange = new EventEmitter(undefined);
2797 this.stepDay = {};
2798 this.stepMonth = {};
2799 this.stepYear = {};
2800 this.modes = ['day', 'month', 'year'];
2801 this.dateFormatter = new DateFormatter();
2802 }
2803 get activeDate() {
2804 return this._activeDate;
2805 }
2806 set activeDate(value) {
2807 this._activeDate = value;
2808 }
2809 // todo: add formatter value to Date object
2810 ngOnInit() {
2811 // todo: use date for unique value
2812 this.uniqueId = `datepicker--${Math.floor(Math.random() * 10000)}`;
2813 if (this.initDate) {
2814 this.activeDate = this.initDate;
2815 this.selectedDate = new Date(this.activeDate.valueOf());
2816 this.update.emit(this.activeDate);
2817 }
2818 else if (this.activeDate === undefined) {
2819 this.activeDate = new Date();
2820 }
2821 }
2822 // this.refreshView should be called here to reflect the changes on the fly
2823 ngOnChanges(changes) {
2824 this.refreshView();
2825 this.checkIfActiveDateGotUpdated(changes.activeDate);
2826 }
2827 // Check if activeDate has been update and then emit the activeDateChange with the new date
2828 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2829 checkIfActiveDateGotUpdated(activeDate) {
2830 if (activeDate && !activeDate.firstChange) {
2831 const previousValue = activeDate.previousValue;
2832 if (previousValue &&
2833 previousValue instanceof Date &&
2834 previousValue.getTime() !== activeDate.currentValue.getTime()) {
2835 this.activeDateChange.emit(this.activeDate);
2836 }
2837 }
2838 }
2839 setCompareHandler(handler, type) {
2840 if (type === 'day') {
2841 this.compareHandlerDay = handler;
2842 }
2843 if (type === 'month') {
2844 this.compareHandlerMonth = handler;
2845 }
2846 if (type === 'year') {
2847 this.compareHandlerYear = handler;
2848 }
2849 }
2850 compare(date1, date2) {
2851 if (date1 === undefined || date2 === undefined) {
2852 return undefined;
2853 }
2854 if (this.datepickerMode === 'day' && this.compareHandlerDay) {
2855 return this.compareHandlerDay(date1, date2);
2856 }
2857 if (this.datepickerMode === 'month' && this.compareHandlerMonth) {
2858 return this.compareHandlerMonth(date1, date2);
2859 }
2860 if (this.datepickerMode === 'year' && this.compareHandlerYear) {
2861 return this.compareHandlerYear(date1, date2);
2862 }
2863 return void 0;
2864 }
2865 setRefreshViewHandler(handler, type) {
2866 if (type === 'day') {
2867 this.refreshViewHandlerDay = handler;
2868 }
2869 if (type === 'month') {
2870 this.refreshViewHandlerMonth = handler;
2871 }
2872 if (type === 'year') {
2873 this.refreshViewHandlerYear = handler;
2874 }
2875 }
2876 refreshView() {
2877 if (this.datepickerMode === 'day' && this.refreshViewHandlerDay) {
2878 this.refreshViewHandlerDay();
2879 }
2880 if (this.datepickerMode === 'month' && this.refreshViewHandlerMonth) {
2881 this.refreshViewHandlerMonth();
2882 }
2883 if (this.datepickerMode === 'year' && this.refreshViewHandlerYear) {
2884 this.refreshViewHandlerYear();
2885 }
2886 }
2887 dateFilter(date, format) {
2888 return this.dateFormatter.format(date, format, this.locale);
2889 }
2890 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2891 isActive(dateObject) {
2892 if (this.compare(dateObject.date, this.activeDate) === 0) {
2893 this.activeDateId = dateObject.uid;
2894 return true;
2895 }
2896 return false;
2897 }
2898 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2899 createDateObject(date, format) {
2900 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2901 const dateObject = {};
2902 dateObject.date = new Date(date.getFullYear(), date.getMonth(), date.getDate());
2903 dateObject.date = this.fixTimeZone(dateObject.date);
2904 dateObject.label = this.dateFilter(date, format);
2905 dateObject.selected = this.compare(date, this.selectedDate) === 0;
2906 dateObject.disabled = this.isDisabled(date);
2907 dateObject.current = this.compare(date, new Date()) === 0;
2908 dateObject.customClass = this.getCustomClassForDate(dateObject.date);
2909 return dateObject;
2910 }
2911 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2912 split(arr, size) {
2913 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2914 const arrays = [];
2915 while (arr.length > 0) {
2916 arrays.push(arr.splice(0, size));
2917 }
2918 return arrays;
2919 }
2920 // Fix a hard-reproducible bug with timezones
2921 // The bug depends on OS, browser, current timezone and current date
2922 // i.e.
2923 // var date = new Date(2014, 0, 1);
2924 // console.log(date.getFullYear(), date.getMonth(), date.getDate(),
2925 // date.getHours()); can result in "2013 11 31 23" because of the bug.
2926 fixTimeZone(date) {
2927 const hours = date.getHours();
2928 return new Date(date.getFullYear(), date.getMonth(), date.getDate(), hours === 23 ? hours + 2 : 0);
2929 }
2930 select(date, isManual = true) {
2931 if (this.datepickerMode === this.minMode) {
2932 if (!this.activeDate) {
2933 this.activeDate = new Date(0, 0, 0, 0, 0, 0, 0);
2934 }
2935 this.activeDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
2936 this.activeDate = this.fixTimeZone(this.activeDate);
2937 if (isManual) {
2938 this.selectionDone.emit(this.activeDate);
2939 }
2940 }
2941 else {
2942 this.activeDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());
2943 this.activeDate = this.fixTimeZone(this.activeDate);
2944 if (isManual && this.datepickerMode) {
2945 this.datepickerMode = this.modes[this.modes.indexOf(this.datepickerMode) - 1];
2946 }
2947 }
2948 this.selectedDate = new Date(this.activeDate.valueOf());
2949 this.update.emit(this.activeDate);
2950 this.refreshView();
2951 }
2952 move(direction) {
2953 // eslint-disable-next-line @typescript-eslint/no-explicit-any
2954 let expectedStep;
2955 if (this.datepickerMode === 'day') {
2956 expectedStep = this.stepDay;
2957 }
2958 if (this.datepickerMode === 'month') {
2959 expectedStep = this.stepMonth;
2960 }
2961 if (this.datepickerMode === 'year') {
2962 expectedStep = this.stepYear;
2963 }
2964 if (expectedStep && this.activeDate) {
2965 const year = this.activeDate.getFullYear() + direction * (expectedStep.years || 0);
2966 const month = this.activeDate.getMonth() + direction * (expectedStep.months || 0);
2967 this.activeDate = new Date(year, month, 1);
2968 this.refreshView();
2969 this.activeDateChange.emit(this.activeDate);
2970 }
2971 }
2972 toggleMode(_direction) {
2973 const direction = _direction || 1;
2974 if ((this.datepickerMode === this.maxMode && direction === 1) ||
2975 (this.datepickerMode === this.minMode && direction === -1)) {
2976 return;
2977 }
2978 if (this.datepickerMode) {
2979 this.datepickerMode = this.modes[this.modes.indexOf(this.datepickerMode) + direction];
2980 }
2981 this.refreshView();
2982 }
2983 getCustomClassForDate(date) {
2984 if (!this.customClass) {
2985 return '';
2986 }
2987 // todo: build a hash of custom classes, it will work faster
2988 const customClassObject = this.customClass.find((customClass) => {
2989 return (customClass.date.valueOf() === date.valueOf() &&
2990 customClass.mode === this.datepickerMode);
2991 }, this);
2992 return customClassObject === undefined ? '' : customClassObject.clazz;
2993 }
2994 compareDateDisabled(date1Disabled, date2) {
2995 if (date1Disabled === undefined || date2 === undefined) {
2996 return undefined;
2997 }
2998 if (date1Disabled.mode === 'day' && this.compareHandlerDay) {
2999 return this.compareHandlerDay(date1Disabled.date, date2);
3000 }
3001 if (date1Disabled.mode === 'month' && this.compareHandlerMonth) {
3002 return this.compareHandlerMonth(date1Disabled.date, date2);
3003 }
3004 if (date1Disabled.mode === 'year' && this.compareHandlerYear) {
3005 return this.compareHandlerYear(date1Disabled.date, date2);
3006 }
3007 return undefined;
3008 }
3009 isDisabled(date) {
3010 let isDateDisabled = false;
3011 if (this.dateDisabled) {
3012 this.dateDisabled.forEach((disabledDate) => {
3013 if (this.compareDateDisabled(disabledDate, date) === 0) {
3014 isDateDisabled = true;
3015 }
3016 });
3017 }
3018 if (this.dayDisabled) {
3019 isDateDisabled =
3020 isDateDisabled ||
3021 this.dayDisabled.indexOf(date.getDay()) > -1;
3022 }
3023 if (isDateDisabled) {
3024 return isDateDisabled;
3025 }
3026 const minDate = Number(this.minDate && this.compare(date, this.minDate));
3027 if (!isNaN(minDate)) {
3028 return minDate < 0;
3029 }
3030 const maxDate = Number(this.maxDate && this.compare(date, this.maxDate));
3031 if (!isNaN(maxDate)) {
3032 return maxDate > 0;
3033 }
3034 return false;
3035 }
3036}
3037DatePickerInnerComponent.decorators = [
3038 { type: Component, args: [{
3039 selector: 'datepicker-inner',
3040 template: `
3041 <!--&lt;!&ndash;ng-keydown="keydown($event)"&ndash;&gt;-->
3042 <div *ngIf='datepickerMode' class='well well-sm bg-faded p-a card' role='application'>
3043 <ng-content></ng-content>
3044 </div>
3045 `
3046 },] }
3047];
3048DatePickerInnerComponent.propDecorators = {
3049 locale: [{ type: Input }],
3050 datepickerMode: [{ type: Input }],
3051 startingDay: [{ type: Input }],
3052 yearRange: [{ type: Input }],
3053 minDate: [{ type: Input }],
3054 maxDate: [{ type: Input }],
3055 minMode: [{ type: Input }],
3056 maxMode: [{ type: Input }],
3057 showWeeks: [{ type: Input }],
3058 formatDay: [{ type: Input }],
3059 formatMonth: [{ type: Input }],
3060 formatYear: [{ type: Input }],
3061 formatDayHeader: [{ type: Input }],
3062 formatDayTitle: [{ type: Input }],
3063 formatMonthTitle: [{ type: Input }],
3064 onlyCurrentMonth: [{ type: Input }],
3065 shortcutPropagation: [{ type: Input }],
3066 customClass: [{ type: Input }],
3067 monthColLimit: [{ type: Input }],
3068 yearColLimit: [{ type: Input }],
3069 dateDisabled: [{ type: Input }],
3070 dayDisabled: [{ type: Input }],
3071 initDate: [{ type: Input }],
3072 selectionDone: [{ type: Output }],
3073 update: [{ type: Output }],
3074 activeDateChange: [{ type: Output }],
3075 activeDate: [{ type: Input }]
3076};
3077
3078class DatepickerConfig {
3079 constructor() {
3080 this.locale = 'en';
3081 this.datepickerMode = 'day';
3082 this.startingDay = 0;
3083 this.yearRange = 20;
3084 this.minMode = 'day';
3085 this.maxMode = 'year';
3086 this.showWeeks = true;
3087 this.formatDay = 'DD';
3088 this.formatMonth = 'MMMM';
3089 this.formatYear = 'YYYY';
3090 this.formatDayHeader = 'dd';
3091 this.formatDayTitle = 'MMMM YYYY';
3092 this.formatMonthTitle = 'YYYY';
3093 this.onlyCurrentMonth = false;
3094 this.monthColLimit = 3;
3095 this.yearColLimit = 5;
3096 this.shortcutPropagation = false;
3097 }
3098}
3099DatepickerConfig.ɵprov = ɵɵdefineInjectable({ factory: function DatepickerConfig_Factory() { return new DatepickerConfig(); }, token: DatepickerConfig, providedIn: "root" });
3100DatepickerConfig.decorators = [
3101 { type: Injectable, args: [{
3102 providedIn: 'root'
3103 },] }
3104];
3105
3106const DATEPICKER_CONTROL_VALUE_ACCESSOR = {
3107 provide: NG_VALUE_ACCESSOR,
3108 useExisting: forwardRef(() => DatePickerComponent),
3109 multi: true
3110};
3111class DatePickerComponent {
3112 constructor(config) {
3113 /** sets datepicker mode, supports: `day`, `month`, `year` */
3114 this.datepickerMode = 'day';
3115 /** if false week numbers will be hidden */
3116 this.showWeeks = true;
3117 /** number of months displayed in a single row of month picker */
3118 this.monthColLimit = 3;
3119 /** number of years displayed in a single row of year picker */
3120 this.yearColLimit = 5;
3121 this.selectionDone = new EventEmitter(undefined);
3122 /** callback to invoke when the activeDate is changed. */
3123 this.activeDateChange = new EventEmitter(undefined);
3124 // eslint-disable-next-line @typescript-eslint/no-explicit-any
3125 this.onChange = Function.prototype;
3126 // eslint-disable-next-line @typescript-eslint/no-explicit-any
3127 this.onTouched = Function.prototype;
3128 this._now = new Date();
3129 this.config = config;
3130 this.configureOptions();
3131 }
3132 /** currently active date */
3133 get activeDate() {
3134 return this._activeDate || this._now;
3135 }
3136 set activeDate(value) {
3137 this._activeDate = value;
3138 }
3139 configureOptions() {
3140 Object.assign(this, this.config);
3141 }
3142 onUpdate(event) {
3143 this.activeDate = event;
3144 this.onChange(event);
3145 }
3146 onSelectionDone(event) {
3147 this.selectionDone.emit(event);
3148 }
3149 onActiveDateChange(event) {
3150 this.activeDateChange.emit(event);
3151 }
3152 // todo: support null value
3153 // eslint-disable-next-line @typescript-eslint/no-explicit-any
3154 writeValue(value) {
3155 var _a, _b;
3156 if (((_a = this._datePicker) === null || _a === void 0 ? void 0 : _a.compare(value, this._activeDate)) === 0) {
3157 return;
3158 }
3159 if (value && value instanceof Date) {
3160 this.activeDate = value;
3161 (_b = this._datePicker) === null || _b === void 0 ? void 0 : _b.select(value, false);
3162 return;
3163 }
3164 this.activeDate = value ? new Date(value) : void 0;
3165 }
3166 registerOnChange(fn) {
3167 this.onChange = fn;
3168 }
3169 registerOnTouched(fn) {
3170 this.onTouched = fn;
3171 }
3172}
3173DatePickerComponent.decorators = [
3174 { type: Component, args: [{
3175 selector: 'datepicker',
3176 template: `
3177 <datepicker-inner [activeDate]="activeDate"
3178 (update)="onUpdate($event)"
3179 [locale]="config.locale"
3180 [datepickerMode]="datepickerMode"
3181 [initDate]="initDate"
3182 [minDate]="minDate"
3183 [maxDate]="maxDate"
3184 [minMode]="minMode"
3185 [maxMode]="maxMode"
3186 [showWeeks]="showWeeks"
3187 [formatDay]="formatDay"
3188 [formatMonth]="formatMonth"
3189 [formatYear]="formatYear"
3190 [formatDayHeader]="formatDayHeader"
3191 [formatDayTitle]="formatDayTitle"
3192 [formatMonthTitle]="formatMonthTitle"
3193 [startingDay]="startingDay"
3194 [yearRange]="yearRange"
3195 [customClass]="customClass"
3196 [dateDisabled]="dateDisabled"
3197 [dayDisabled]="dayDisabled"
3198 [onlyCurrentMonth]="onlyCurrentMonth"
3199 [shortcutPropagation]="shortcutPropagation"
3200 [monthColLimit]="monthColLimit"
3201 [yearColLimit]="yearColLimit"
3202 (selectionDone)="onSelectionDone($event)"
3203 (activeDateChange)="onActiveDateChange($event)">
3204 <daypicker tabindex="0"></daypicker>
3205 <monthpicker tabindex="0"></monthpicker>
3206 <yearpicker tabindex="0"></yearpicker>
3207 </datepicker-inner>
3208 `,
3209 providers: [DATEPICKER_CONTROL_VALUE_ACCESSOR]
3210 },] }
3211];
3212DatePickerComponent.ctorParameters = () => [
3213 { type: DatepickerConfig }
3214];
3215DatePickerComponent.propDecorators = {
3216 datepickerMode: [{ type: Input }],
3217 initDate: [{ type: Input }],
3218 minDate: [{ type: Input }],
3219 maxDate: [{ type: Input }],
3220 minMode: [{ type: Input }],
3221 maxMode: [{ type: Input }],
3222 showWeeks: [{ type: Input }],
3223 formatDay: [{ type: Input }],
3224 formatMonth: [{ type: Input }],
3225 formatYear: [{ type: Input }],
3226 formatDayHeader: [{ type: Input }],
3227 formatDayTitle: [{ type: Input }],
3228 formatMonthTitle: [{ type: Input }],
3229 startingDay: [{ type: Input }],
3230 yearRange: [{ type: Input }],
3231 onlyCurrentMonth: [{ type: Input }],
3232 shortcutPropagation: [{ type: Input }],
3233 monthColLimit: [{ type: Input }],
3234 yearColLimit: [{ type: Input }],
3235 customClass: [{ type: Input }],
3236 dateDisabled: [{ type: Input }],
3237 dayDisabled: [{ type: Input }],
3238 activeDate: [{ type: Input }],
3239 selectionDone: [{ type: Output }],
3240 activeDateChange: [{ type: Output }],
3241 _datePicker: [{ type: ViewChild, args: [DatePickerInnerComponent, { static: true },] }]
3242};
3243
3244// @deprecated
3245class DayPickerComponent {
3246 constructor(datePicker) {
3247 this.labels = [];
3248 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3249 // @ts-ignore
3250 // eslint-disable-next-line @typescript-eslint/no-explicit-any
3251 this.rows = [];
3252 this.weekNumbers = [];
3253 this.datePicker = datePicker;
3254 }
3255 get isBs4() {
3256 return !isBs3();
3257 }
3258 /*protected getDaysInMonth(year:number, month:number) {
3259 return ((month === 1) && (year % 4 === 0) &&
3260 ((year % 100 !== 0) || (year % 400 === 0))) ? 29 : DAYS_IN_MONTH[month];
3261 }*/
3262 ngOnInit() {
3263 // eslint-disable-next-line @typescript-eslint/no-this-alias
3264 const self = this;
3265 this.datePicker.stepDay = { months: 1 };
3266 // todo valorkin fix
3267 this.datePicker.setRefreshViewHandler(function () {
3268 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3269 // @ts-ignore
3270 // eslint-disable-next-line @typescript-eslint/no-this-alias
3271 const that = this;
3272 const year = that.activeDate.getFullYear();
3273 const month = that.activeDate.getMonth();
3274 const firstDayOfMonth = new Date(year, month, 1);
3275 const difference = that.startingDay - firstDayOfMonth.getDay();
3276 const numDisplayedFromPreviousMonth = difference > 0 ? 7 - difference : -difference;
3277 const firstDate = new Date(firstDayOfMonth.getTime());
3278 if (numDisplayedFromPreviousMonth > 0) {
3279 firstDate.setDate(-numDisplayedFromPreviousMonth + 1);
3280 }
3281 // 42 is the number of days on a six-week calendar
3282 const _days = self.getDates(firstDate, 42);
3283 const days = [];
3284 for (let i = 0; i < 42; i++) {
3285 const _dateObject = that.createDateObject(_days[i], that.formatDay);
3286 _dateObject.secondary = _days[i].getMonth() !== month;
3287 _dateObject.uid = that.uniqueId + '-' + i;
3288 days[i] = _dateObject;
3289 }
3290 self.labels = [];
3291 for (let j = 0; j < 7; j++) {
3292 self.labels[j] = {};
3293 self.labels[j].abbr = that.dateFilter(days[j].date, that.formatDayHeader);
3294 self.labels[j].full = that.dateFilter(days[j].date, 'EEEE');
3295 }
3296 self.title = that.dateFilter(that.activeDate, that.formatDayTitle);
3297 self.rows = that.split(days, 7);
3298 if (that.showWeeks) {
3299 self.weekNumbers = [];
3300 const thursdayIndex = (4 + 7 - that.startingDay) % 7;
3301 const numWeeks = self.rows.length;
3302 for (let curWeek = 0; curWeek < numWeeks; curWeek++) {
3303 const _date = self.rows[curWeek][thursdayIndex].date;
3304 if (_date) {
3305 self.weekNumbers.push(self.getISO8601WeekNumber(_date));
3306 }
3307 }
3308 }
3309 }, 'day');
3310 this.datePicker.setCompareHandler(function (date1, date2) {
3311 const d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
3312 const d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
3313 return d1.getTime() - d2.getTime();
3314 }, 'day');
3315 this.datePicker.refreshView();
3316 }
3317 getDates(startDate, n) {
3318 const dates = new Array(n);
3319 let current = new Date(startDate.getTime());
3320 let i = 0;
3321 let date;
3322 while (i < n) {
3323 date = new Date(current.getTime());
3324 date = this.datePicker.fixTimeZone(date);
3325 dates[i++] = date;
3326 current = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1);
3327 }
3328 return dates;
3329 }
3330 getISO8601WeekNumber(date) {
3331 const checkDate = new Date(date.getTime());
3332 // Thursday
3333 checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
3334 const time = checkDate.getTime();
3335 // Compare with Jan 1
3336 checkDate.setMonth(0);
3337 checkDate.setDate(1);
3338 return (Math.floor(Math.round((time - checkDate.getTime()) / 86400000) / 7) + 1);
3339 }
3340}
3341DayPickerComponent.decorators = [
3342 { type: Component, args: [{
3343 selector: 'daypicker',
3344 template: `
3345<table *ngIf="datePicker.datepickerMode === 'day'" role="grid" [attr.aria-labelledby]="datePicker.uniqueId + '-title'" aria-activedescendant="activeDateId">
3346 <thead>
3347 <tr>
3348 <th>
3349 <button *ngIf="!isBs4"
3350 type="button"
3351 class="btn btn-default btn-secondary btn-sm pull-left float-left"
3352 (click)="datePicker.move(-1)"
3353 tabindex="-1">‹</button>
3354 <button *ngIf="isBs4"
3355 type="button"
3356 class="btn btn-default btn-secondary btn-sm pull-left float-left"
3357 (click)="datePicker.move(-1)"
3358 tabindex="-1">&lt;</button>
3359 </th>
3360 <th [attr.colspan]="5 + (datePicker.showWeeks ? 1 : 0)">
3361 <button [id]="datePicker.uniqueId + '-title'"
3362 type="button" class="btn btn-default btn-secondary btn-sm"
3363 (click)="datePicker.toggleMode(0)"
3364 [disabled]="datePicker.datepickerMode === datePicker.maxMode"
3365 [ngClass]="{disabled: datePicker.datepickerMode === datePicker.maxMode}" tabindex="-1" style="width:100%;">
3366 <strong>{{ title }}</strong>
3367 </button>
3368 </th>
3369 <th>
3370 <button *ngIf="!isBs4"
3371 type="button"
3372 class="btn btn-default btn-secondary btn-sm pull-right float-right"
3373 (click)="datePicker.move(1)"
3374 tabindex="-1">›</button>
3375 <button *ngIf="isBs4"
3376 type="button"
3377 class="btn btn-default btn-secondary btn-sm pull-right float-right"
3378 (click)="datePicker.move(1)"
3379 tabindex="-1">&gt;
3380 </button>
3381 </th>
3382 </tr>
3383 <tr>
3384 <th *ngIf="datePicker.showWeeks"></th>
3385 <th *ngFor="let labelz of labels" class="text-center">
3386 <small aria-label="labelz.full"><b>{{ labelz.abbr }}</b></small>
3387 </th>
3388 </tr>
3389 </thead>
3390 <tbody>
3391 <ng-template ngFor [ngForOf]="rows" let-rowz="$implicit" let-index="index">
3392 <tr *ngIf="!(datePicker.onlyCurrentMonth && rowz[0].secondary && rowz[6].secondary)">
3393 <td *ngIf="datePicker.showWeeks" class="h6" class="text-center">
3394 <em>{{ weekNumbers[index] }}</em>
3395 </td>
3396 <td *ngFor="let dtz of rowz" class="text-center" role="gridcell" [id]="dtz.uid">
3397 <button type="button" style="min-width:100%;" class="btn btn-sm {{dtz.customClass}}"
3398 *ngIf="!(datePicker.onlyCurrentMonth && dtz.secondary)"
3399 [ngClass]="{'btn-secondary': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected, disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz), 'btn-default': !isBs4}"
3400 [disabled]="dtz.disabled"
3401 (click)="datePicker.select(dtz.date)" tabindex="-1">
3402 <span [ngClass]="{'text-muted': dtz.secondary || dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
3403 </button>
3404 </td>
3405 </tr>
3406 </ng-template>
3407 </tbody>
3408</table>
3409 `,
3410 styles: [`
3411 :host .btn-secondary {
3412 color: #292b2c;
3413 background-color: #fff;
3414 border-color: #ccc;
3415 }
3416 :host .btn-info .text-muted {
3417 color: #292b2c !important;
3418 }
3419 `]
3420 },] }
3421];
3422DayPickerComponent.ctorParameters = () => [
3423 { type: DatePickerInnerComponent }
3424];
3425
3426// @deprecated
3427class MonthPickerComponent {
3428 constructor(datePicker) {
3429 this.rows = [];
3430 this.datePicker = datePicker;
3431 }
3432 get isBs4() {
3433 return !isBs3();
3434 }
3435 ngOnInit() {
3436 // eslint-disable-next-line @typescript-eslint/no-this-alias
3437 const self = this;
3438 this.datePicker.stepMonth = { years: 1 };
3439 this.datePicker.setRefreshViewHandler(function () {
3440 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3441 // @ts-ignore
3442 // eslint-disable-next-line @typescript-eslint/no-this-alias
3443 const that = this;
3444 const months = new Array(12);
3445 const year = that.activeDate.getFullYear();
3446 let date;
3447 for (let i = 0; i < 12; i++) {
3448 date = new Date(year, i, 1);
3449 date = that.fixTimeZone(date);
3450 months[i] = that.createDateObject(date, that.formatMonth);
3451 months[i].uid = that.uniqueId + '-' + i;
3452 }
3453 self.title = that.dateFilter(that.activeDate, that.formatMonthTitle);
3454 self.rows = that.split(months, self.datePicker.monthColLimit);
3455 }, 'month');
3456 this.datePicker.setCompareHandler(function (date1, date2) {
3457 const d1 = new Date(date1.getFullYear(), date1.getMonth());
3458 const d2 = new Date(date2.getFullYear(), date2.getMonth());
3459 return d1.getTime() - d2.getTime();
3460 }, 'month');
3461 this.datePicker.refreshView();
3462 }
3463}
3464MonthPickerComponent.decorators = [
3465 { type: Component, args: [{
3466 selector: 'monthpicker',
3467 template: `
3468<table *ngIf="datePicker.datepickerMode==='month'" role="grid">
3469 <thead>
3470 <tr>
3471 <th>
3472 <button type="button" class="btn btn-default btn-sm pull-left float-left"
3473 (click)="datePicker.move(-1)" tabindex="-1">‹</button></th>
3474 <th [attr.colspan]="((datePicker.monthColLimit - 2) <= 0) ? 1 : datePicker.monthColLimit - 2">
3475 <button [id]="datePicker.uniqueId + '-title'"
3476 type="button" class="btn btn-default btn-sm"
3477 (click)="datePicker.toggleMode(0)"
3478 [disabled]="datePicker.datepickerMode === maxMode"
3479 [ngClass]="{disabled: datePicker.datepickerMode === maxMode}" tabindex="-1" style="width:100%;">
3480 <strong>{{ title }}</strong>
3481 </button>
3482 </th>
3483 <th>
3484 <button type="button" class="btn btn-default btn-sm pull-right float-right"
3485 (click)="datePicker.move(1)" tabindex="-1">›</button>
3486 </th>
3487 </tr>
3488 </thead>
3489 <tbody>
3490 <tr *ngFor="let rowz of rows">
3491 <td *ngFor="let dtz of rowz" class="text-center" role="gridcell" [attr.id]="dtz.uid" [ngClass]="dtz.customClass">
3492 <button type="button" style="min-width:100%;" class="btn btn-default"
3493 [ngClass]="{'btn-link': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected || (isBs4 && !dtz.selected && datePicker.isActive(dtz)), disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz)}"
3494 [disabled]="dtz.disabled"
3495 (click)="datePicker.select(dtz.date)" tabindex="-1">
3496 <span [ngClass]="{'text-success': isBs4 && dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
3497 </button>
3498 </td>
3499 </tr>
3500 </tbody>
3501</table>
3502 `,
3503 styles: [`
3504 :host .btn-info .text-success {
3505 color: #fff !important;
3506 }
3507 `]
3508 },] }
3509];
3510MonthPickerComponent.ctorParameters = () => [
3511 { type: DatePickerInnerComponent }
3512];
3513
3514// @deprecated
3515class YearPickerComponent {
3516 constructor(datePicker) {
3517 this.rows = [];
3518 this.datePicker = datePicker;
3519 }
3520 get isBs4() {
3521 return !isBs3();
3522 }
3523 ngOnInit() {
3524 // eslint-disable-next-line @typescript-eslint/no-this-alias
3525 const self = this;
3526 this.datePicker.stepYear = { years: this.datePicker.yearRange };
3527 this.datePicker.setRefreshViewHandler(function () {
3528 // eslint-disable-next-line @typescript-eslint/ban-ts-comment
3529 // @ts-ignore
3530 // eslint-disable-next-line @typescript-eslint/no-this-alias
3531 const that = this;
3532 const years = new Array(that.yearRange);
3533 let date;
3534 const start = self.getStartingYear(that.activeDate.getFullYear()) || 0;
3535 for (let i = 0; i < that.yearRange; i++) {
3536 date = new Date(start + i, 0, 1);
3537 date = that.fixTimeZone(date);
3538 years[i] = that.createDateObject(date, that.formatYear);
3539 years[i].uid = that.uniqueId + '-' + i;
3540 }
3541 self.title = [years[0].label, years[that.yearRange - 1].label].join(' - ');
3542 self.rows = that.split(years, self.datePicker.yearColLimit);
3543 }, 'year');
3544 this.datePicker.setCompareHandler(function (date1, date2) {
3545 return date1.getFullYear() - date2.getFullYear();
3546 }, 'year');
3547 this.datePicker.refreshView();
3548 }
3549 getStartingYear(year) {
3550 // todo: parseInt
3551 if (this.datePicker && this.datePicker.yearRange) {
3552 return ((year - 1) / this.datePicker.yearRange * this.datePicker.yearRange + 1);
3553 }
3554 return undefined;
3555 }
3556}
3557YearPickerComponent.decorators = [
3558 { type: Component, args: [{
3559 selector: 'yearpicker',
3560 template: `
3561 <table *ngIf="datePicker.datepickerMode==='year'" role='grid'>
3562 <thead>
3563 <tr>
3564 <th>
3565 <button type='button' class='btn btn-default btn-sm pull-left float-left'
3566 (click)='datePicker.move(-1)' tabindex='-1'>‹
3567 </button>
3568 </th>
3569 <th [attr.colspan]='((datePicker.yearColLimit - 2) <= 0) ? 1 : datePicker.yearColLimit - 2'>
3570 <button [id]="datePicker.uniqueId + '-title'" role='heading'
3571 type='button' class='btn btn-default btn-sm'
3572 (click)='datePicker.toggleMode(0)'
3573 [disabled]='datePicker.datepickerMode === datePicker.maxMode'
3574 [ngClass]='{disabled: datePicker.datepickerMode === datePicker.maxMode}' tabindex='-1'
3575 style='width:100%;'>
3576 <strong>{{ title }}</strong>
3577 </button>
3578 </th>
3579 <th>
3580 <button type='button' class='btn btn-default btn-sm pull-right float-right'
3581 (click)='datePicker.move(1)' tabindex='-1'>›
3582 </button>
3583 </th>
3584 </tr>
3585 </thead>
3586 <tbody>
3587 <tr *ngFor='let rowz of rows'>
3588 <td *ngFor='let dtz of rowz' class='text-center' role='gridcell' [attr.id]='dtz.uid'>
3589 <button type='button' style='min-width:100%;' class='btn btn-default'
3590 [ngClass]="{'btn-link': isBs4 && !dtz.selected && !datePicker.isActive(dtz), 'btn-info': dtz.selected || (isBs4 && !dtz.selected && datePicker.isActive(dtz)), disabled: dtz.disabled, active: !isBs4 && datePicker.isActive(dtz)}"
3591 [disabled]='dtz.disabled'
3592 (click)='datePicker.select(dtz.date)' tabindex='-1'>
3593 <span
3594 [ngClass]="{'text-success': isBs4 && dtz.current, 'text-info': !isBs4 && dtz.current}">{{ dtz.label }}</span>
3595 </button>
3596 </td>
3597 </tr>
3598 </tbody>
3599 </table>
3600 `,
3601 styles: [`
3602 :host .btn-info .text-success {
3603 color: #fff !important;
3604 }
3605 `]
3606 },] }
3607];
3608YearPickerComponent.ctorParameters = () => [
3609 { type: DatePickerInnerComponent }
3610];
3611
3612class BsCalendarLayoutComponent {
3613}
3614BsCalendarLayoutComponent.decorators = [
3615 { type: Component, args: [{
3616 selector: 'bs-calendar-layout',
3617 template: `
3618 <!-- current date, will be added in nearest releases -->
3619 <bs-current-date title="hey there" *ngIf="false"></bs-current-date>
3620
3621 <!--navigation-->
3622 <div class="bs-datepicker-head">
3623 <ng-content select="bs-datepicker-navigation-view"></ng-content>
3624 </div>
3625
3626 <div class="bs-datepicker-body">
3627 <ng-content></ng-content>
3628 </div>
3629
3630 <!--timepicker-->
3631 <bs-timepicker *ngIf="false"></bs-timepicker>
3632 `
3633 },] }
3634];
3635
3636class BsCurrentDateViewComponent {
3637}
3638BsCurrentDateViewComponent.decorators = [
3639 { type: Component, args: [{
3640 selector: 'bs-current-date',
3641 template: `<div class="current-timedate"><span>{{ title }}</span></div>`
3642 },] }
3643];
3644BsCurrentDateViewComponent.propDecorators = {
3645 title: [{ type: Input }]
3646};
3647
3648class BsCustomDatesViewComponent {
3649 constructor() {
3650 this.onSelect = new EventEmitter();
3651 }
3652 selectFromRanges(range) {
3653 this.onSelect.emit(range);
3654 }
3655}
3656BsCustomDatesViewComponent.decorators = [
3657 { type: Component, args: [{
3658 selector: 'bs-custom-date-view',
3659 template: `
3660 <div class="bs-datepicker-predefined-btns">
3661 <button *ngFor="let range of ranges"
3662 type="button"
3663 class="btn"
3664 (click)="selectFromRanges(range)"
3665 [class.selected]="range.value === selectedRange">
3666 {{ range.label }}
3667 </button>
3668 </div>
3669 `,
3670 changeDetection: ChangeDetectionStrategy.OnPush
3671 },] }
3672];
3673BsCustomDatesViewComponent.propDecorators = {
3674 ranges: [{ type: Input }],
3675 selectedRange: [{ type: Input }],
3676 customRangeLabel: [{ type: Input }],
3677 onSelect: [{ type: Output }]
3678};
3679
3680class BsDatepickerDayDecoratorComponent {
3681 constructor(_config, _elRef, _renderer) {
3682 this._config = _config;
3683 this._elRef = _elRef;
3684 this._renderer = _renderer;
3685 this.day = { date: new Date(), label: '' };
3686 }
3687 ngOnInit() {
3688 var _a, _b, _c;
3689 if (((_a = this.day) === null || _a === void 0 ? void 0 : _a.isToday) && this._config && this._config.customTodayClass) {
3690 this._renderer.addClass(this._elRef.nativeElement, this._config.customTodayClass);
3691 }
3692 if (typeof ((_b = this.day) === null || _b === void 0 ? void 0 : _b.customClasses) === 'string') {
3693 (_c = this.day) === null || _c === void 0 ? void 0 : _c.customClasses.split(' ').filter((className) => className).forEach((className) => {
3694 this._renderer.addClass(this._elRef.nativeElement, className);
3695 });
3696 }
3697 }
3698}
3699BsDatepickerDayDecoratorComponent.decorators = [
3700 { type: Component, args: [{
3701 selector: '[bsDatepickerDayDecorator]',
3702 changeDetection: ChangeDetectionStrategy.OnPush,
3703 host: {
3704 '[class.disabled]': 'day.isDisabled',
3705 '[class.is-highlighted]': 'day.isHovered',
3706 '[class.is-other-month]': 'day.isOtherMonth',
3707 '[class.is-active-other-month]': 'day.isOtherMonthHovered',
3708 '[class.in-range]': 'day.isInRange',
3709 '[class.select-start]': 'day.isSelectionStart',
3710 '[class.select-end]': 'day.isSelectionEnd',
3711 '[class.selected]': 'day.isSelected'
3712 },
3713 template: `{{ day && day.label || '' }}`
3714 },] }
3715];
3716BsDatepickerDayDecoratorComponent.ctorParameters = () => [
3717 { type: BsDatepickerConfig },
3718 { type: ElementRef },
3719 { type: Renderer2 }
3720];
3721BsDatepickerDayDecoratorComponent.propDecorators = {
3722 day: [{ type: Input }]
3723};
3724
3725/** *************** */
3726// events
3727/** *************** */
3728var BsNavigationDirection;
3729(function (BsNavigationDirection) {
3730 BsNavigationDirection[BsNavigationDirection["UP"] = 0] = "UP";
3731 BsNavigationDirection[BsNavigationDirection["DOWN"] = 1] = "DOWN";
3732})(BsNavigationDirection || (BsNavigationDirection = {}));
3733
3734class BsDatepickerNavigationViewComponent {
3735 constructor() {
3736 this.onNavigate = new EventEmitter();
3737 this.onViewMode = new EventEmitter();
3738 }
3739 navTo(down) {
3740 this.onNavigate.emit(down ? BsNavigationDirection.DOWN : BsNavigationDirection.UP);
3741 }
3742 view(viewMode) {
3743 this.onViewMode.emit(viewMode);
3744 }
3745}
3746BsDatepickerNavigationViewComponent.decorators = [
3747 { type: Component, args: [{
3748 selector: 'bs-datepicker-navigation-view',
3749 changeDetection: ChangeDetectionStrategy.OnPush,
3750 template: `
3751 <button class="previous"
3752 [disabled]="calendar.disableLeftArrow"
3753 [style.visibility]="calendar.hideLeftArrow ? 'hidden' : 'visible'"
3754 type="button"
3755 (click)="navTo(true)">
3756 <span>&lsaquo;</span>
3757 </button>
3758
3759 <ng-container *ngIf="calendar && calendar.monthTitle">
3760 &#8203; <!-- zero-width space needed for correct alignment
3761 with preserveWhitespaces: false in Angular -->
3762
3763 <button class="current"
3764 type="button"
3765 (click)="view('month')"
3766 ><span>{{ calendar.monthTitle }}</span>
3767 </button>
3768 </ng-container>
3769
3770 &#8203; <!-- zero-width space needed for correct alignment
3771 with preserveWhitespaces: false in Angular -->
3772
3773 <button class="current" (click)="view('year')" type="button">
3774 <span>{{ calendar.yearTitle }}</span>
3775 </button>
3776
3777 &#8203; <!-- zero-width space needed for correct alignment
3778 with preserveWhitespaces: false in Angular -->
3779
3780 <button class="next"
3781 [disabled]="calendar.disableRightArrow"
3782 [style.visibility]="calendar.hideRightArrow ? 'hidden' : 'visible'"
3783 type="button"
3784 (click)="navTo(false)"><span>&rsaquo;</span>
3785 </button>
3786 `
3787 },] }
3788];
3789BsDatepickerNavigationViewComponent.propDecorators = {
3790 calendar: [{ type: Input }],
3791 onNavigate: [{ type: Output }],
3792 onViewMode: [{ type: Output }]
3793};
3794
3795class BsDaysCalendarViewComponent {
3796 constructor(_config) {
3797 this._config = _config;
3798 this.onNavigate = new EventEmitter();
3799 this.onViewMode = new EventEmitter();
3800 this.onSelect = new EventEmitter();
3801 this.onHover = new EventEmitter();
3802 this.onHoverWeek = new EventEmitter();
3803 this.isiOS = (/iPad|iPhone|iPod/.test(navigator.platform) ||
3804 (navigator.platform === 'MacIntel' && navigator.maxTouchPoints > 1));
3805 if (this._config.dateTooltipTexts && this._config.dateTooltipTexts.length > 0) {
3806 this.isShowTooltip = true;
3807 }
3808 }
3809 navigateTo(event) {
3810 const step = BsNavigationDirection.DOWN === event ? -1 : 1;
3811 this.onNavigate.emit({ step: { month: step } });
3812 }
3813 changeViewMode(event) {
3814 this.onViewMode.emit(event);
3815 }
3816 selectDay(event) {
3817 this.onSelect.emit(event);
3818 }
3819 selectWeek(week) {
3820 if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
3821 return;
3822 }
3823 if (week.days.length === 0) {
3824 return;
3825 }
3826 if (this._config.selectWeek && week.days[0]
3827 && !week.days[0].isDisabled
3828 && this._config.selectFromOtherMonth) {
3829 this.onSelect.emit(week.days[0]);
3830 return;
3831 }
3832 const selectedDay = week.days.find((day) => {
3833 return this._config.selectFromOtherMonth
3834 ? !day.isDisabled
3835 : !day.isOtherMonth && !day.isDisabled;
3836 });
3837 this.onSelect.emit(selectedDay);
3838 if (this._config.selectWeekDateRange) {
3839 const days = week.days.slice(0);
3840 const lastDayOfRange = days.reverse().find((day) => {
3841 return this._config.selectFromOtherMonth
3842 ? !day.isDisabled
3843 : !day.isOtherMonth && !day.isDisabled;
3844 });
3845 this.onSelect.emit(lastDayOfRange);
3846 }
3847 }
3848 weekHoverHandler(cell, isHovered) {
3849 if (!this._config.selectWeek && !this._config.selectWeekDateRange) {
3850 return;
3851 }
3852 const hasActiveDays = cell.days.find((day) => {
3853 return this._config.selectFromOtherMonth
3854 ? !day.isDisabled
3855 : !day.isOtherMonth && !day.isDisabled;
3856 });
3857 if (hasActiveDays) {
3858 cell.isHovered = isHovered;
3859 this.isWeekHovered = isHovered;
3860 this.onHoverWeek.emit(cell);
3861 }
3862 }
3863 hoverDay(cell, isHovered) {
3864 if (this._config.selectFromOtherMonth && cell.isOtherMonth) {
3865 cell.isOtherMonthHovered = isHovered;
3866 }
3867 if (this._config.dateTooltipTexts) {
3868 cell.tooltipText = '';
3869 this._config.dateTooltipTexts.forEach((dateData) => {
3870 if (isSameDay(dateData.date, cell.date)) {
3871 cell.tooltipText = dateData.tooltipText;
3872 return;
3873 }
3874 });
3875 }
3876 this.onHover.emit({ cell, isHovered });
3877 }
3878}
3879BsDaysCalendarViewComponent.decorators = [
3880 { type: Component, args: [{
3881 selector: 'bs-days-calendar-view',
3882 // changeDetection: ChangeDetectionStrategy.OnPush,
3883 template: `
3884 <bs-calendar-layout>
3885 <bs-datepicker-navigation-view
3886 [calendar]="calendar"
3887 (onNavigate)="navigateTo($event)"
3888 (onViewMode)="changeViewMode($event)"
3889 ></bs-datepicker-navigation-view>
3890 <!--days matrix-->
3891 <table role="grid" class="days weeks">
3892 <thead>
3893 <tr>
3894 <!--if show weeks-->
3895 <th *ngIf="options && options.showWeekNumbers"></th>
3896 <th *ngFor="let weekday of calendar.weekdays; let i = index"
3897 aria-label="weekday">{{ calendar.weekdays[i] }}
3898 </th>
3899 </tr>
3900 </thead>
3901 <tbody>
3902 <tr *ngFor="let week of calendar.weeks; let i = index">
3903 <td class="week" [class.active-week]="isWeekHovered" *ngIf="options && options.showWeekNumbers">
3904 <span *ngIf="isiOS" (click)="selectWeek(week)">{{ calendar.weekNumbers[i] }}</span>
3905 <span *ngIf="!isiOS"
3906 (click)="selectWeek(week)"
3907 (mouseenter)="weekHoverHandler(week, true)"
3908 (mouseleave)="weekHoverHandler(week, false)">{{ calendar.weekNumbers[i] }}</span>
3909 </td>
3910 <td *ngFor="let day of week.days" role="gridcell">
3911
3912 <!-- When we want to show tooltips for dates -->
3913 <span *ngIf="!isiOS && isShowTooltip" bsDatepickerDayDecorator
3914 [day]="day"
3915 (click)="selectDay(day)"
3916 tooltip="{{day.tooltipText}}"
3917 (mouseenter)="hoverDay(day, true)"
3918 (mouseleave)="hoverDay(day, false)">{{ day.label }} 3</span>
3919 <!-- When tooltips for dates are disabled -->
3920 <span *ngIf="!isiOS && !isShowTooltip" bsDatepickerDayDecorator
3921 [day]="day"
3922 (click)="selectDay(day)"
3923 (mouseenter)="hoverDay(day, true)"
3924 (mouseleave)="hoverDay(day, false)">{{ day.label }} 2</span>
3925
3926 <!-- For mobile iOS view, tooltips are not needed -->
3927 <span *ngIf="isiOS" bsDatepickerDayDecorator
3928 [day]="day"
3929 (click)="selectDay(day)">{{ day.label }} 1</span>
3930 </td>
3931 </tr>
3932 </tbody>
3933 </table>
3934
3935 </bs-calendar-layout>
3936 `
3937 },] }
3938];
3939BsDaysCalendarViewComponent.ctorParameters = () => [
3940 { type: BsDatepickerConfig }
3941];
3942BsDaysCalendarViewComponent.propDecorators = {
3943 calendar: [{ type: Input }],
3944 options: [{ type: Input }],
3945 onNavigate: [{ type: Output }],
3946 onViewMode: [{ type: Output }],
3947 onSelect: [{ type: Output }],
3948 onHover: [{ type: Output }],
3949 onHoverWeek: [{ type: Output }]
3950};
3951
3952class BsMonthCalendarViewComponent {
3953 constructor() {
3954 this.onNavigate = new EventEmitter();
3955 this.onViewMode = new EventEmitter();
3956 this.onSelect = new EventEmitter();
3957 this.onHover = new EventEmitter();
3958 }
3959 navigateTo(event) {
3960 const step = BsNavigationDirection.DOWN === event ? -1 : 1;
3961 this.onNavigate.emit({ step: { year: step } });
3962 }
3963 viewMonth(month) {
3964 this.onSelect.emit(month);
3965 }
3966 hoverMonth(cell, isHovered) {
3967 this.onHover.emit({ cell, isHovered });
3968 }
3969 changeViewMode(event) {
3970 this.onViewMode.emit(event);
3971 }
3972}
3973BsMonthCalendarViewComponent.decorators = [
3974 { type: Component, args: [{
3975 selector: 'bs-month-calendar-view',
3976 template: `
3977 <bs-calendar-layout>
3978 <bs-datepicker-navigation-view
3979 [calendar]="calendar"
3980 (onNavigate)="navigateTo($event)"
3981 (onViewMode)="changeViewMode($event)"
3982 ></bs-datepicker-navigation-view>
3983
3984 <table role="grid" class="months">
3985 <tbody>
3986 <tr *ngFor="let row of calendar?.months">
3987 <td *ngFor="let month of row" role="gridcell"
3988 (click)="viewMonth(month)"
3989 (mouseenter)="hoverMonth(month, true)"
3990 (mouseleave)="hoverMonth(month, false)"
3991 [class.disabled]="month.isDisabled"
3992 [class.is-highlighted]="month.isHovered">
3993 <span [class.selected]="month.isSelected">{{ month.label }}</span>
3994 </td>
3995 </tr>
3996 </tbody>
3997 </table>
3998 </bs-calendar-layout>
3999 `
4000 },] }
4001];
4002BsMonthCalendarViewComponent.propDecorators = {
4003 calendar: [{ type: Input }],
4004 onNavigate: [{ type: Output }],
4005 onViewMode: [{ type: Output }],
4006 onSelect: [{ type: Output }],
4007 onHover: [{ type: Output }]
4008};
4009
4010class BsTimepickerViewComponent {
4011 constructor() {
4012 this.ampm = 'ok';
4013 this.hours = 0;
4014 this.minutes = 0;
4015 }
4016}
4017BsTimepickerViewComponent.decorators = [
4018 { type: Component, args: [{
4019 selector: 'bs-timepicker',
4020 template: `
4021 <div class="bs-timepicker-container">
4022 <div class="bs-timepicker-controls">
4023 <button class="bs-decrease" type="button">-</button>
4024 <input type="text" [value]="hours" placeholder="00">
4025 <button class="bs-increase" type="button">+</button>
4026 </div>
4027 <div class="bs-timepicker-controls">
4028 <button class="bs-decrease" type="button">-</button>
4029 <input type="text" [value]="minutes" placeholder="00">
4030 <button class="bs-increase" type="button">+</button>
4031 </div>
4032 <button class="switch-time-format" type="button">{{ ampm }}
4033 <img
4034 src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAsAAAAKCAYAAABi8KSDAAABSElEQVQYV3XQPUvDUBQG4HNuagtVqc6KgouCv6GIuIntYBLB9hcIQpLStCAIV7DYmpTcRWcXqZio3Vwc/UCc/QEqfgyKGbr0I7nS1EiHeqYzPO/h5SD0jaxUZjmSLCB+OFb+UFINFwASAEAdpu9gaGXVyAHHFQBkHpKHc6a9dzECvADyY9sqlAMsK9W0jzxDXqeytr3mhQckxSji27TJJ5/rPmIpwJJq3HrtduriYOurv1a4i1p5HnhkG9OFymi0ReoO05cGwb+ayv4dysVygjeFmsP05f8wpZQ8fsdvfmuY9zjWSNqUtgYFVnOVReILYoBFzdQI5/GGFzNHhGbeZnopDGU29sZbscgldmC99w35VOATTycIMMcBXIfpSVGzZhA6C8hh00conln6VQ9TGgV32OEAKQC4DrBq7CJwd0ggR7Vq/rPrfgB+C3sGypY5DAAAAABJRU5ErkJggg=="
4035 alt="">
4036 </button>
4037 </div>
4038 `
4039 },] }
4040];
4041
4042class BsYearsCalendarViewComponent {
4043 constructor() {
4044 this.onNavigate = new EventEmitter();
4045 this.onViewMode = new EventEmitter();
4046 this.onSelect = new EventEmitter();
4047 this.onHover = new EventEmitter();
4048 }
4049 navigateTo(event) {
4050 const step = BsNavigationDirection.DOWN === event ? -1 : 1;
4051 this.onNavigate.emit({ step: { year: step * yearsPerCalendar } });
4052 }
4053 viewYear(year) {
4054 this.onSelect.emit(year);
4055 }
4056 hoverYear(cell, isHovered) {
4057 this.onHover.emit({ cell, isHovered });
4058 }
4059 changeViewMode(event) {
4060 this.onViewMode.emit(event);
4061 }
4062}
4063BsYearsCalendarViewComponent.decorators = [
4064 { type: Component, args: [{
4065 selector: 'bs-years-calendar-view',
4066 template: `
4067 <bs-calendar-layout>
4068 <bs-datepicker-navigation-view
4069 [calendar]="calendar"
4070 (onNavigate)="navigateTo($event)"
4071 (onViewMode)="changeViewMode($event)"
4072 ></bs-datepicker-navigation-view>
4073
4074 <table role="grid" class="years">
4075 <tbody>
4076 <tr *ngFor="let row of calendar?.years">
4077 <td *ngFor="let year of row" role="gridcell"
4078 (click)="viewYear(year)"
4079 (mouseenter)="hoverYear(year, true)"
4080 (mouseleave)="hoverYear(year, false)"
4081 [class.disabled]="year.isDisabled"
4082 [class.is-highlighted]="year.isHovered">
4083 <span [class.selected]="year.isSelected">{{ year.label }}</span>
4084 </td>
4085 </tr>
4086 </tbody>
4087 </table>
4088 </bs-calendar-layout>
4089 `
4090 },] }
4091];
4092BsYearsCalendarViewComponent.propDecorators = {
4093 calendar: [{ type: Input }],
4094 onNavigate: [{ type: Output }],
4095 onViewMode: [{ type: Output }],
4096 onSelect: [{ type: Output }],
4097 onHover: [{ type: Output }]
4098};
4099
4100class BsDatepickerModule {
4101 static forRoot() {
4102 return {
4103 ngModule: BsDatepickerModule,
4104 providers: [
4105 ComponentLoaderFactory,
4106 PositioningService,
4107 BsDatepickerStore,
4108 BsDatepickerActions,
4109 BsDatepickerEffects,
4110 BsLocaleService
4111 ]
4112 };
4113 }
4114}
4115BsDatepickerModule.decorators = [
4116 { type: NgModule, args: [{
4117 imports: [CommonModule, TooltipModule],
4118 declarations: [
4119 BsCalendarLayoutComponent,
4120 BsCurrentDateViewComponent,
4121 BsCustomDatesViewComponent,
4122 BsDatepickerDayDecoratorComponent,
4123 BsDatepickerNavigationViewComponent,
4124 BsDaysCalendarViewComponent,
4125 BsMonthCalendarViewComponent,
4126 BsTimepickerViewComponent,
4127 BsYearsCalendarViewComponent,
4128 BsDatepickerContainerComponent,
4129 BsDatepickerDirective,
4130 BsDatepickerInlineContainerComponent,
4131 BsDatepickerInlineDirective,
4132 BsDatepickerInputDirective,
4133 BsDaterangepickerContainerComponent,
4134 BsDaterangepickerDirective,
4135 BsDaterangepickerInlineContainerComponent,
4136 BsDaterangepickerInlineDirective,
4137 BsDaterangepickerInputDirective
4138 ],
4139 entryComponents: [
4140 BsDatepickerContainerComponent,
4141 BsDaterangepickerContainerComponent,
4142 BsDatepickerInlineContainerComponent,
4143 BsDaterangepickerInlineContainerComponent
4144 ],
4145 exports: [
4146 BsDatepickerContainerComponent,
4147 BsDatepickerDirective,
4148 BsDatepickerInlineContainerComponent,
4149 BsDatepickerInlineDirective,
4150 BsDatepickerInputDirective,
4151 BsDaterangepickerContainerComponent,
4152 BsDaterangepickerDirective,
4153 BsDaterangepickerInlineContainerComponent,
4154 BsDaterangepickerInlineDirective,
4155 BsDaterangepickerInputDirective
4156 ]
4157 },] }
4158];
4159
4160class DatepickerModule {
4161 static forRoot() {
4162 return { ngModule: DatepickerModule, providers: [DatepickerConfig] };
4163 }
4164}
4165DatepickerModule.decorators = [
4166 { type: NgModule, args: [{
4167 imports: [CommonModule, FormsModule],
4168 declarations: [
4169 DatePickerComponent,
4170 DatePickerInnerComponent,
4171 DayPickerComponent,
4172 MonthPickerComponent,
4173 YearPickerComponent
4174 ],
4175 exports: [
4176 DatePickerComponent,
4177 DatePickerInnerComponent,
4178 DayPickerComponent,
4179 MonthPickerComponent,
4180 YearPickerComponent
4181 ],
4182 entryComponents: [DatePickerComponent]
4183 },] }
4184];
4185
4186/**
4187 * Generated bundle index. Do not edit.
4188 */
4189
4190export { BsDatepickerConfig, BsDatepickerContainerComponent, BsDatepickerDirective, BsDatepickerInlineConfig, BsDatepickerInlineContainerComponent, BsDatepickerInlineDirective, BsDatepickerInputDirective, BsDatepickerModule, BsDaterangepickerConfig, BsDaterangepickerContainerComponent, BsDaterangepickerDirective, BsDaterangepickerInlineConfig, BsDaterangepickerInlineContainerComponent, BsDaterangepickerInlineDirective, BsDaterangepickerInputDirective, BsLocaleService, DateFormatter, DatePickerComponent, DatePickerInnerComponent, DatepickerConfig, DatepickerModule, DayPickerComponent, MonthPickerComponent, YearPickerComponent, DATEPICKER_CONTROL_VALUE_ACCESSOR as ɵa, BsDatepickerAbstractComponent as ɵb, BsDatepickerStore as ɵc, BsDatepickerEffects as ɵd, BsDatepickerActions as ɵe, datepickerAnimation as ɵf, BsCalendarLayoutComponent as ɵg, BsCurrentDateViewComponent as ɵh, BsCustomDatesViewComponent as ɵi, BsDatepickerDayDecoratorComponent as ɵj, BsDatepickerNavigationViewComponent as ɵk, BsDaysCalendarViewComponent as ɵl, BsMonthCalendarViewComponent as ɵm, BsTimepickerViewComponent as ɵn, BsYearsCalendarViewComponent as ɵo };
4191//# sourceMappingURL=ngx-bootstrap-datepicker.js.map