ng-material-date-range-picker
Version:
This library provides the date range selection with two views.
759 lines (753 loc) • 52.9 kB
JavaScript
import * as i0 from '@angular/core';
import { signal, ChangeDetectorRef, inject, ElementRef, Renderer2, Component, ChangeDetectionStrategy, Input, ViewChild, EventEmitter, computed, Output, NgModule } from '@angular/core';
import * as i1 from '@angular/material/datepicker';
import { DateRange, MatDatepickerModule } from '@angular/material/datepicker';
import * as i1$1 from '@angular/common';
import { DatePipe, CommonModule } from '@angular/common';
import * as i2 from '@angular/material/input';
import { MatInputModule } from '@angular/material/input';
import * as i3 from '@angular/material/form-field';
import { MatFormFieldModule } from '@angular/material/form-field';
import * as i4 from '@angular/cdk/overlay';
import { OverlayModule } from '@angular/cdk/overlay';
import * as i5 from '@angular/material/icon';
import { MatIconModule } from '@angular/material/icon';
import * as i6 from '@angular/material/button';
import { MatButtonModule } from '@angular/material/button';
import * as i7 from '@angular/material/list';
import { MatListModule } from '@angular/material/list';
import * as i8 from '@angular/material/tooltip';
import { MatTooltipModule } from '@angular/material/tooltip';
import { FormsModule } from '@angular/forms';
import { MatAutocompleteModule } from '@angular/material/autocomplete';
import { MatNativeDateModule } from '@angular/material/core';
/**
* @(#)date-filter-enum.ts Sept 08, 2023
*
* @author Aakash Kumar
*/
const ACTIVE_DATE_DEBOUNCE = 100;
var DATE_OPTION_TYPE;
(function (DATE_OPTION_TYPE) {
DATE_OPTION_TYPE[DATE_OPTION_TYPE["DATE_DIFF"] = 1] = "DATE_DIFF";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["LAST_MONTH"] = 2] = "LAST_MONTH";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["THIS_MONTH"] = 3] = "THIS_MONTH";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["YEAR_TO_DATE"] = 4] = "YEAR_TO_DATE";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["CUSTOM"] = 5] = "CUSTOM";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["MONTH_TO_DATE"] = 6] = "MONTH_TO_DATE";
DATE_OPTION_TYPE[DATE_OPTION_TYPE["WEEK_TO_DATE"] = 7] = "WEEK_TO_DATE";
})(DATE_OPTION_TYPE || (DATE_OPTION_TYPE = {}));
/**
* Resets the selection state for all options
* and marks the given option as selected if provided.
*
* @param options - List of date options
* @param selectedOption - Option to be marked as selected
*/
function resetOptionSelection(options, selectedOption) {
options.forEach((option) => (option.isSelected = false));
if (selectedOption) {
selectedOption.isSelected = true;
}
}
/**
* Marks the custom date option as selected.
*
* @param options - List of date options
*/
function selectCustomOption(options) {
const customOption = options.find((option) => option.optionType === DATE_OPTION_TYPE.CUSTOM);
if (customOption)
customOption.isSelected = true;
}
/**
* Returns a new date with the given year offset applied.
*
* @param offset - Number of years to add (negative for past years)
* @returns Date object with updated year
*/
function getDateWithOffset(offset) {
const date = new Date();
date.setFullYear(date.getFullYear() + offset);
return date;
}
/**
* Creates a deep clone of the provided object or array.
*
* @param data - Data to be cloned
* @returns A deep copy of the data
*/
function getClone(data) {
return JSON.parse(JSON.stringify(data));
}
/**
* Formats a date object into a string using Angular DatePipe.
*
* @param date - Date to be formatted
* @param dateFormat - Desired date format (e.g., 'dd/MM/yyyy')
* @returns Formatted date string
*/
function getDateString(date, dateFormat) {
const datePipe = new DatePipe('en');
return datePipe.transform(date, dateFormat) ?? '';
}
/**
* Formats a date range into a string with start and end dates.
*
* @param range - Date range with start and end
* @param dateFormat - Desired date format
* @returns Formatted range string (e.g., '01/01/2023 - 07/01/2023')
*/
function getFormattedDateString(range, dateFormat) {
if (!(range.start && range.end)) {
return '';
}
return (getDateString(range.start, dateFormat) +
' - ' +
getDateString(range.end, dateFormat));
}
/**
* Creates a standardized date option object for dropdowns.
*
* @param label - Display label for the option
* @param key - Option key from DEFAULT_DATE_OPTION_ENUM
* @param dateDiff - Offset in days from current date (default: 0)
* @param isVisible - Whether the option is visible (default: true)
* @returns ISelectDateOption object
*/
function createOption(label, key, dateDiff = 0, isVisible = true) {
return {
optionLabel: label,
optionType: key,
dateDiff,
isSelected: false,
isVisible,
};
}
/**
* Returns the date of the next month based on the given date.
*
* @param currDate - Current date
* @returns A new Date object incremented by one month
*/
function getDateOfNextMonth(currDate) {
const date = new Date(currDate);
date.setMonth(currDate.getMonth() + 1);
return date;
}
/**
* Returns the first day of the month following the given date.
*
* @param currDate - The current date
* @returns A Date object set to the first day of the next month
*/
function getFirstDateOfNextMonth(currDate) {
return new Date(currDate.getFullYear(), currDate.getMonth() + 1, 1);
}
/**
* Returns the number of days in the month of the given date.
*
* @param date The date to calculate the days for.
* @returns Number of days in the month.
*/
function getDaysInMonth(date) {
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
}
/**
* Overrides the `activeDate` setter for a MatCalendar instance, injecting custom handler logic
* while preserving the original setter behavior. Useful for reacting to internal date navigation
* events (e.g., month changes) in Angular Material's calendar.
*
* @param calendar - Instance of MatCalendar whose `activeDate` setter will be overridden.
* @param cdref - ChangeDetectorRef to trigger view updates after the setter runs.
* @param handler - Custom callback function executed whenever `activeDate` is set.
*/
function overrideActiveDateSetter(calendar, cdref, handler) {
const proto = Object.getPrototypeOf(calendar);
const descriptor = Object.getOwnPropertyDescriptor(proto, 'activeDate');
if (!(descriptor?.set && descriptor?.get)) {
console.warn('overrideActiveDateSetter: activeDate setter/getter not found on MatCalendar prototype.');
return;
}
const originalSetter = descriptor.set;
const originalGetter = descriptor.get;
Object.defineProperty(calendar, 'activeDate', {
configurable: true,
enumerable: false,
get() {
return originalGetter.call(this);
},
set(value) {
const activeDate = {
previous: originalGetter.call(this) ?? value,
current: value,
};
originalSetter.call(this, value);
handler.call(this, activeDate);
cdref.markForCheck();
},
});
}
/**
* @(#)default-date-options.ts Sept 08, 2023
*
* @author Aakash Kumar
*/
const DEFAULT_DATE_OPTIONS = [
createOption('Today', DATE_OPTION_TYPE.DATE_DIFF, 0),
createOption('Yesterday', DATE_OPTION_TYPE.DATE_DIFF, -1),
createOption('Last 7 Days', DATE_OPTION_TYPE.DATE_DIFF, -7),
createOption('Last 30 Days', DATE_OPTION_TYPE.DATE_DIFF, -30),
createOption('Last Month', DATE_OPTION_TYPE.LAST_MONTH),
createOption('This Month', DATE_OPTION_TYPE.THIS_MONTH),
createOption('Month To Date', DATE_OPTION_TYPE.MONTH_TO_DATE),
createOption('Week To Date', DATE_OPTION_TYPE.WEEK_TO_DATE, 0, false),
createOption('Year To Date', DATE_OPTION_TYPE.YEAR_TO_DATE),
createOption('Custom Range', DATE_OPTION_TYPE.CUSTOM),
];
/**
* @(#)calendar.component.scss Sept 07, 2023
*
* Custom Calendar Component that manages two side-by-side
* month views with support for date range selection, hover
* highlighting, and navigation controls.
*
* @author Aakash Kumar
*/
class CalendarComponent {
constructor() {
this.firstViewStartDate = signal(new Date());
this.secondViewStartDate = signal(getDateOfNextMonth(this.firstViewStartDate()));
this.secondViewMinDate = signal(getFirstDateOfNextMonth(this.firstViewStartDate()));
this.isAllowHoverEvent = false;
this.cdref = inject(ChangeDetectorRef);
this.el = inject(ElementRef);
this.renderer = inject(Renderer2);
}
/**
* Updates the selected date range and synchronizes both calendar views.
*/
set selectedDates(selectedDates) {
this._selectedDates = selectedDates;
if (!selectedDates || !(selectedDates.start && selectedDates.end))
return;
const startDate = selectedDates.start ?? new Date();
const endDate = selectedDates.end;
this.firstViewStartDate.set(startDate);
this.secondViewMinDate.set(getFirstDateOfNextMonth(startDate));
const computedEndDate = startDate.getMonth() === endDate.getMonth()
? getDateOfNextMonth(endDate)
: endDate;
this.secondViewStartDate.set(computedEndDate);
}
get selectedDates() {
return this._selectedDates;
}
/**
* Lifecycle hook that is called after Angular has fully initialized
* the component's view (and child views).
*
* Used here to attach hover events and register active date change
* listeners once the calendar views are available in the DOM.
*/
ngAfterViewInit() {
this.attachHoverEvent('firstCalendarView');
this.attachHoverEvent('secondCalendarView');
this.registerActiveDateChangeEvents();
}
/**
* Handles month selection in the first view.
*
* @param event - Selected month date
*/
monthSelected(viewName) {
if (viewName === 'secondCalendarView') {
this.removeDefaultFocus(this);
}
this.attachHoverEvent(viewName);
}
/**
* Updates the selected date range when a date is clicked.
*
* @param date - Date clicked by the user
*/
updateDateRangeSelection(date) {
const selectedDates = this.selectedDates;
if (!selectedDates ||
(selectedDates.start && selectedDates.end) ||
(selectedDates.start && date && selectedDates.start > date)) {
this._selectedDates = new DateRange(date, null);
this.isAllowHoverEvent = true;
}
else {
this.isAllowHoverEvent = false;
this._selectedDates = new DateRange(selectedDates.start, date);
}
this.cdref.markForCheck();
}
/**
* Registers event handlers for active date changes on both calendar views.
*
* This method overrides the default `activeDate` property setter of each
* calendar view to ensure custom handlers are executed whenever the
* active date changes.
*/
registerActiveDateChangeEvents() {
overrideActiveDateSetter(this.firstCalendarView, this.cdref, this.onFirstViewActiveDateChange.bind(this));
overrideActiveDateSetter(this.secondCalendarView, this.cdref, this.onSecondViewActiveDateChange.bind(this));
}
/**
* Handles the event when the active date of the first calendar view changes.
*
* @param activeDate - Object containing `previous` and `current` date values.
*/
onFirstViewActiveDateChange(activeDate) {
const handler = this.isPrevious(activeDate)
? () => this.handleFirstViewPrevEvent(activeDate)
: () => this.handleFirstViewNextEvent(activeDate.current);
// Delay execution because active date event fires before view update
setTimeout(handler, ACTIVE_DATE_DEBOUNCE);
}
/**
* Handles the event when the active date of the second calendar view changes.
*
* @param activeDate - Object containing `previous` and `current` date values.
*/
onSecondViewActiveDateChange(activeDate) {
this.attachHoverEvent('secondCalendarView');
}
/**
* Handles the "next" navigation event for the first calendar view.
*
* @param currDate - The currently active date in the first calendar view.
* @param force - Optional flag that can be used to enforce updates (not used in current logic).
*/
handleFirstViewNextEvent(currDate, force) {
if (this.firstCalendarView.currentView.toLocaleLowerCase() !== 'month') {
return;
}
this.attachHoverEvent('firstCalendarView');
const nextMonthDate = getFirstDateOfNextMonth(currDate);
let secondViewActiveDate = this.secondCalendarView.activeDate;
if (nextMonthDate < secondViewActiveDate) {
this.secondViewMinDate.set(nextMonthDate);
this.attachHoverEvent('secondCalendarView');
return;
}
secondViewActiveDate = getDateOfNextMonth(currDate);
this.secondViewMinDate.set(nextMonthDate);
this.secondCalendarView.activeDate = secondViewActiveDate;
this.cdref.detectChanges();
}
/**
* Handles the "previous" navigation event for the first calendar view.
*
* @param activeDate - Object containing `previous` and `current` date values.
*/
handleFirstViewPrevEvent(activeDate) {
if (this.firstCalendarView.currentView.toLocaleLowerCase() !== 'month') {
return;
}
this.secondViewMinDate.set(getFirstDateOfNextMonth(activeDate.current));
this.attachHoverEvent('firstCalendarView');
this.attachHoverEvent('secondCalendarView');
}
/**
* Checks whether the previous date is greater than the current date.
*
* @param activeDate - Object containing `previous` and `current` date values.
* @returns `true` if the previous date is later than the current date, otherwise `false`.
*/
isPrevious(activeDate) {
return activeDate.previous > activeDate.current;
}
/**
* Attaches hover events to all date cells in the first view.
*/
attachHoverEvent(viewId) {
const nodes = this.el.nativeElement.querySelectorAll(`#${viewId} .mat-calendar-body-cell`);
setTimeout(() => this.addHoverEvents(nodes), ACTIVE_DATE_DEBOUNCE);
}
/**
* Removes active focus from the second view.
*
* @param classRef - Reference to this component
*/
removeDefaultFocus(classRef) {
setTimeout(() => {
const btn = classRef.el.nativeElement.querySelectorAll('#secondCalendarView button.mat-calendar-body-active');
if (btn?.length) {
btn[0].blur();
}
}, 1);
}
/**
* Updates the selection range dynamically on hover.
*
* @param date - Hovered date
*/
updateSelectionOnMouseHover(date) {
const selectedDates = this.selectedDates;
if (selectedDates?.start && date && selectedDates.start < date) {
const dateRange = new DateRange(selectedDates.start, date);
this.firstCalendarView.selected = dateRange;
this.secondCalendarView.selected = dateRange;
this.firstCalendarView['_changeDetectorRef'].markForCheck();
this.secondCalendarView['_changeDetectorRef'].markForCheck();
this.isAllowHoverEvent = true;
}
}
/**
* Attaches hover events to given nodes to update range selection.
*
* @param nodes - Date cell nodes
*/
addHoverEvents(nodes) {
if (!nodes) {
return;
}
Array.from(nodes).forEach((button) => {
this.renderer.listen(button, 'mouseover', (event) => {
if (this.isAllowHoverEvent) {
const date = new Date(event.target['ariaLabel']);
this.updateSelectionOnMouseHover(date);
}
});
});
this.firstCalendarView['_changeDetectorRef'].markForCheck();
this.secondCalendarView['_changeDetectorRef'].markForCheck();
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CalendarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.0.6", type: CalendarComponent, selector: "lib-calendar", inputs: { minDate: "minDate", maxDate: "maxDate", selectedDates: "selectedDates" }, viewQueries: [{ propertyName: "firstCalendarView", first: true, predicate: ["firstCalendarView"], descendants: true }, { propertyName: "secondCalendarView", first: true, predicate: ["secondCalendarView"], descendants: true }], ngImport: i0, template: "<!--**\r\n * @(#)calendar.component.html Sept 07, 2023\r\n\r\n * @author Aakash Kumar\r\n *-->\r\n<div class=\"calendar-container\">\r\n <div class=\"first-view\">\r\n <mat-calendar id=\"firstCalendarView\" #firstCalendarView [startAt]=\"firstViewStartDate()\" [selected]=\"selectedDates\"\r\n (selectedChange)=\"updateDateRangeSelection($event)\" (monthSelected)=\"monthSelected('firstCalendarView')\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"></mat-calendar>\r\n </div>\r\n <div class=\"second-view\">\r\n <mat-calendar id=\"secondCalendarView\" #secondCalendarView [startAt]=\"secondViewStartDate()\" [minDate]=\"secondViewMinDate()\"\r\n [maxDate]=\"maxDate\" [selected]=\"selectedDates\" (selectedChange)=\"updateDateRangeSelection($event)\"\r\n (monthSelected)=\"monthSelected('secondCalendarView')\"></mat-calendar>\r\n </div>\r\n</div>\r\n", styles: [".mat-calendar{min-width:250px}.calendar-container{width:100%;display:block;float:left}.first-view,.second-view{width:50%;display:block;float:left}.first-view,.second-view{margin-top:.5rem}@media (max-width: 490px){.first-view,.second-view{width:100%}}\n"], dependencies: [{ kind: "component", type: i1.MatCalendar, selector: "mat-calendar", inputs: ["headerComponent", "startAt", "startView", "selected", "minDate", "maxDate", "dateFilter", "dateClass", "comparisonStart", "comparisonEnd", "startDateAccessibleName", "endDateAccessibleName"], outputs: ["selectedChange", "yearSelected", "monthSelected", "viewChanged", "_userSelection", "_userDragDrop"], exportAs: ["matCalendar"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: CalendarComponent, decorators: [{
type: Component,
args: [{ selector: 'lib-calendar', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--**\r\n * @(#)calendar.component.html Sept 07, 2023\r\n\r\n * @author Aakash Kumar\r\n *-->\r\n<div class=\"calendar-container\">\r\n <div class=\"first-view\">\r\n <mat-calendar id=\"firstCalendarView\" #firstCalendarView [startAt]=\"firstViewStartDate()\" [selected]=\"selectedDates\"\r\n (selectedChange)=\"updateDateRangeSelection($event)\" (monthSelected)=\"monthSelected('firstCalendarView')\" [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"></mat-calendar>\r\n </div>\r\n <div class=\"second-view\">\r\n <mat-calendar id=\"secondCalendarView\" #secondCalendarView [startAt]=\"secondViewStartDate()\" [minDate]=\"secondViewMinDate()\"\r\n [maxDate]=\"maxDate\" [selected]=\"selectedDates\" (selectedChange)=\"updateDateRangeSelection($event)\"\r\n (monthSelected)=\"monthSelected('secondCalendarView')\"></mat-calendar>\r\n </div>\r\n</div>\r\n", styles: [".mat-calendar{min-width:250px}.calendar-container{width:100%;display:block;float:left}.first-view,.second-view{width:50%;display:block;float:left}.first-view,.second-view{margin-top:.5rem}@media (max-width: 490px){.first-view,.second-view{width:100%}}\n"] }]
}], propDecorators: { minDate: [{
type: Input
}], maxDate: [{
type: Input
}], firstCalendarView: [{
type: ViewChild,
args: ['firstCalendarView']
}], secondCalendarView: [{
type: ViewChild,
args: ['secondCalendarView']
}], selectedDates: [{
type: Input
}] } });
/**
* @(#)ng-date-picker.component.ts Sept 05, 2023
*
* @author Aakash Kumar
*/
class NgDatePickerComponent {
constructor() {
this.isDateOptionList = false;
this.isCustomRange = false;
this.inputLabel = 'Date Range';
this.staticOptionId = 'static-options';
this.dynamicOptionId = 'dynamic-options';
this.calendarId = 'custom-calendar';
this.enableDefaultOptions = true;
this.dateFormat = 'dd/MM/yyyy';
this.isShowStaticDefaultOptions = false;
this.hideDefaultOptions = false;
this.cdkConnectedOverlayOffsetX = 0;
this.cdkConnectedOverlayOffsetY = 0;
this.listCdkConnectedOverlayOffsetY = 0;
this.listCdkConnectedOverlayOffsetX = 0;
this.selectedOptionIndex = 3;
this.displaySelectedLabel = false;
this.cdkConnectedOverlayPush = true;
this.cdkConnectedOverlayPositions = [];
// default min date is current date - 10 years.
this.minDate = getDateWithOffset(-10);
// default max date is current date + 10 years.
this.maxDate = getDateWithOffset(10);
this.onDateSelectionChanged = new EventEmitter();
this.dateListOptions = new EventEmitter();
this.cdref = inject(ChangeDetectorRef);
this.el = inject(ElementRef);
this._dateOptions = signal([]);
this.visibleOptions = computed(() => this._dateOptions().filter((op) => op.isVisible));
}
set dateDropDownOptions(defaultDateList) {
const options = [
...(this.enableDefaultOptions ? getClone(DEFAULT_DATE_OPTIONS) : []),
...(defaultDateList ?? []),
];
this._dateOptions.set(options);
}
get dateDropDownOptions() {
return this._dateOptions() ?? [];
}
ngOnInit() {
if (this.isDefaultInitRequired()) {
this.initDefaultOptions();
}
this.dateListOptions.emit(this.dateDropDownOptions);
}
ngAfterViewInit() {
this.updateDefaultDatesValues();
}
/**
* Toggles the visibility of the default date option list.
* If the custom option is selected, toggles the custom date range view instead.
*
* @param event Optional MouseEvent triggering the toggle.
*/
toggleDateOptionSelectionList(event) {
event?.preventDefault();
event?.stopImmediatePropagation();
const isCustomSelected = this.dateDropDownOptions.find((option) => option.isSelected)
?.optionType === DATE_OPTION_TYPE.CUSTOM;
if (isCustomSelected) {
this.toggleCustomDateRangeView();
return;
}
this.isDateOptionList = !this.isDateOptionList;
}
/**
* Updates the custom date range selection from the input.
*
* @param input The HTML input element associated with the date picker.
* @param selectedDates The selected date range.
*/
updateCustomRange(input, selectedDates) {
if (this.isCustomRange) {
resetOptionSelection(this.dateDropDownOptions);
selectCustomOption(this.dateDropDownOptions);
this.isCustomRange = false;
}
const start = selectedDates?.start ?? new Date();
const end = selectedDates?.end ?? new Date();
this.updateSelectedDates(input, start, end, null);
}
/**
* Updates the selection when a specific date option is clicked.
*
* @param option The selected date option.
* @param input The HTML input element to update with selected dates.
*/
updateSelection(option, input) {
this.isDateOptionList = false;
this.isCustomRange = option.optionType === DATE_OPTION_TYPE.CUSTOM;
if (!this.isCustomRange) {
resetOptionSelection(this.dateDropDownOptions, option);
this.updateDateOnOptionSelect(option, input);
}
this.cdref.markForCheck();
}
/**
* Toggles the custom date range selection view visibility.
*/
toggleCustomDateRangeView() {
this.isCustomRange = !this.isCustomRange;
}
/**
* Clears the currently selected dates and resets all related properties.
*
* @param event The MouseEvent triggering the clear action.
*/
clearSelection(event) {
event?.stopImmediatePropagation();
this.minDate = getDateWithOffset(-10);
this.maxDate = getDateWithOffset(10);
this.selectedDates = null;
resetOptionSelection(this.dateDropDownOptions);
this.clearDateInput();
this.cdref.markForCheck();
const selectedDateEventData = {
range: null,
selectedOption: null,
};
this.onDateSelectionChanged.emit(selectedDateEventData);
}
/**
* Clears the input field value for the date picker.
*/
clearDateInput() {
const dateInputField = this.el.nativeElement.querySelector('#date-input-field');
if (dateInputField) {
dateInputField.value = '';
}
}
/**
* Updates selected dates based on a selected option and input element.
*
* @param option The selected date option.
* @param input The HTML input element to update.
*/
updateDateOnOptionSelect(option, input) {
// If there is a callback function, use it to get the date range
if (option?.callBackFunction) {
const dateRange = option.callBackFunction();
if (dateRange?.start && dateRange?.end) {
this.updateSelectedDates(input, dateRange.start, dateRange.end, option);
return;
}
}
this.updateDateWithSelectedOption(option, input);
}
/**
* Calculates and updates the start and end dates based on the selected option.
*
* @param option The selected date option.
* @param input The HTML input element to update.
*/
updateDateWithSelectedOption(option, input) {
const currDate = new Date();
let startDate = new Date();
let lastDate = new Date();
// Determine the date range based on the option key
switch (option.optionType) {
case DATE_OPTION_TYPE.DATE_DIFF:
startDate.setDate(startDate.getDate() + (option.dateDiff ?? 0));
break;
case DATE_OPTION_TYPE.LAST_MONTH:
currDate.setMonth(currDate.getMonth() - 1);
startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);
lastDate = new Date(currDate.getFullYear(), currDate.getMonth(), getDaysInMonth(currDate));
break;
case DATE_OPTION_TYPE.THIS_MONTH:
startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);
lastDate = new Date(currDate.getFullYear(), currDate.getMonth(), getDaysInMonth(currDate));
break;
case DATE_OPTION_TYPE.YEAR_TO_DATE:
startDate = new Date(currDate.getFullYear(), 0, 1);
break;
case DATE_OPTION_TYPE.MONTH_TO_DATE:
startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);
break;
default:
break;
}
// Update the selected dates
this.updateSelectedDates(input, startDate, lastDate, option);
}
/**
* Updates the date range and input display.
*
* @param input The HTML input element.
* @param start Start date of the range.
* @param end End date of the range.
* @param opt Optional selected date option.
*/
updateSelectedDates(input, start, end, opt) {
const range = new DateRange(start, end);
this.selectedDates = range;
const label = this.displaySelectedLabel ? opt?.optionLabel : null;
const rangeLabel = `${getDateString(start, this.dateFormat)} - ${getDateString(end, this.dateFormat)}`;
input.value = label ?? rangeLabel;
this.onDateSelectionChanged.emit({
range,
selectedOption: this.dateDropDownOptions.find((o) => o.isSelected) ?? null,
});
this.cdref.markForCheck();
}
/**
* Updates the input and internal state with default dates on initialization.
*/
updateDefaultDatesValues() {
const input = this.el.nativeElement.querySelector('#date-input-field');
if (this.selectedDates?.start && this.selectedDates?.end) {
this._dateOptions().find((option) => option.optionType === DATE_OPTION_TYPE.CUSTOM).isSelected = true;
input.value = getFormattedDateString(this.selectedDates, this.dateFormat);
this.cdref.detectChanges();
return;
}
const selectedOptions = this._dateOptions().find((option) => option.isSelected);
if (selectedOptions &&
selectedOptions.optionType !== DATE_OPTION_TYPE.CUSTOM) {
this.updatedFromListValueSelection(selectedOptions, input);
this.cdref.detectChanges();
}
}
/**
* Updates the input and selected dates based on a selected option from the list.
*
* @param selectedOption The selected date option.
* @param input The HTML input element to update.
*/
updatedFromListValueSelection(selectedOption, input) {
// This will update value if option is selected from default list.
if (!selectedOption['callBackFunction']) {
this.updateDateOnOptionSelect(selectedOption, input);
return;
}
// This will update value if option is selected from provided custom list.
const dateRange = selectedOption.callBackFunction();
this.updateSelectedDates(input, dateRange.start ?? new Date(), dateRange.end ?? new Date(), selectedOption);
}
/**
* Checks whether default initialization of options is required.
*
* @returns True if default options need to be initialized, otherwise false.
*/
isDefaultInitRequired() {
return this.enableDefaultOptions && !this._dateOptions.length;
}
/**
* Initializes the default date options with the selected index.
*/
initDefaultOptions() {
const options = getClone(DEFAULT_DATE_OPTIONS).map((opt, idx) => ({
...opt,
isSelected: idx === this.selectedOptionIndex,
}));
this._dateOptions.set(options);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: NgDatePickerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "17.0.6", type: NgDatePickerComponent, selector: "ng-date-range-picker", inputs: { inputLabel: "inputLabel", staticOptionId: "staticOptionId", dynamicOptionId: "dynamicOptionId", calendarId: "calendarId", enableDefaultOptions: "enableDefaultOptions", selectedDates: "selectedDates", dateFormat: "dateFormat", isShowStaticDefaultOptions: "isShowStaticDefaultOptions", hideDefaultOptions: "hideDefaultOptions", cdkConnectedOverlayOffsetX: "cdkConnectedOverlayOffsetX", cdkConnectedOverlayOffsetY: "cdkConnectedOverlayOffsetY", listCdkConnectedOverlayOffsetY: "listCdkConnectedOverlayOffsetY", listCdkConnectedOverlayOffsetX: "listCdkConnectedOverlayOffsetX", selectedOptionIndex: "selectedOptionIndex", displaySelectedLabel: "displaySelectedLabel", cdkConnectedOverlayPush: "cdkConnectedOverlayPush", cdkConnectedOverlayPositions: "cdkConnectedOverlayPositions", minDate: "minDate", maxDate: "maxDate", dateDropDownOptions: "dateDropDownOptions" }, outputs: { onDateSelectionChanged: "onDateSelectionChanged", dateListOptions: "dateListOptions" }, ngImport: i0, template: "<!--**\r\n * @(#)ng-date-picker.component.html Sept 05, 2023\r\n\r\n * @author Aakash Kumar\r\n *-->\r\n<div class=\"date-picker-main\" cdkOverlayOrigin #trigger>\r\n <mat-form-field class=\"w-full\" [class]=\"{'display-hidden':isShowStaticDefaultOptions}\" (click)=\"toggleDateOptionSelectionList($event)\">\r\n <mat-label (click)=\"toggleDateOptionSelectionList($event)\">{{inputLabel}}</mat-label>\r\n <input matInput readonly=\"readonly\" #dateInput class=\"cursor-pointer\" id=\"date-input-field\">\r\n <button mat-icon-button matSuffix class=\"cursor-pointer pe-0 ps-0\" matTooltip=\"Clear\" *ngIf=\"!!dateInput.value\"\r\n (click)=\"clearSelection($event)\"><mat-icon>clear</mat-icon></button>\r\n <button mat-icon-button matSuffix class=\"cursor-pointer\"> <mat-icon>date_range</mat-icon></button>\r\n </mat-form-field>\r\n\r\n @if(dateDropDownOptions.length && isShowStaticDefaultOptions) {\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput,\r\n optionId: staticOptionId, className:'w-full custom-ckd-container range-input'\r\n }\"></ng-container>\r\n }\r\n\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayHasBackdrop]=\"false\" [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isDateOptionList\" [cdkConnectedOverlayPush]=\"cdkConnectedOverlayPush\"\r\n [cdkConnectedOverlayOffsetX]=\"listCdkConnectedOverlayOffsetX\" [cdkConnectedOverlayOffsetY]=\"listCdkConnectedOverlayOffsetY\"\r\n (overlayOutsideClick)=\"!isShowStaticDefaultOptions && toggleDateOptionSelectionList()\">\r\n\r\n @if(dateDropDownOptions.length && !isShowStaticDefaultOptions) {\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput,\r\n optionId: dynamicOptionId, className:'w-full custom-ckd-container range-input'\r\n }\"></ng-container>\r\n }\r\n </ng-template>\r\n\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayHasBackdrop]=\"false\" [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isCustomRange\" [cdkConnectedOverlayPush]=\"cdkConnectedOverlayPush\"\r\n [cdkConnectedOverlayPositions]=\"cdkConnectedOverlayPositions\" [cdkConnectedOverlayOffsetX]=\"cdkConnectedOverlayOffsetX\"\r\n [cdkConnectedOverlayOffsetY]=\"cdkConnectedOverlayOffsetY\" (overlayOutsideClick)=\"toggleCustomDateRangeView()\">\r\n <div class=\"custom-ckd-container custom-calendar-container\" [class]=\"{'without-default-opt':hideDefaultOptions}\">\r\n <div class=\"row-1\">\r\n <div class=\"pt-custom br-right column-1\" *ngIf=\"!hideDefaultOptions\">\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput}\"></ng-container>\r\n </div>\r\n <div class=\"mt-2 column-2\"><lib-calendar [selectedDates]=\"selectedDates\" #calendar [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"></lib-calendar></div>\r\n </div>\r\n <div class=\"row-2 br-top\">\r\n <div class=\"text-end my-2 w-full\">\r\n <div class=\"footer-content\">\r\n <span id=\"range-label-text\">\r\n {{calendar?.selectedDates?.start | date: dateFormat}}\r\n @if (calendar?.selectedDates?.end) {\r\n <span> - {{calendar.selectedDates?.end | date:\r\n dateFormat}} </span>\r\n }\r\n </span>\r\n <div class=\"d-inline buttons\">\r\n <button mat-button mat-raised-button class=\"p-3 mx-2\" (click)=\"isCustomRange=false;\">Cancel</button>\r\n <button mat-button mat-raised-button color=\"primary\" class=\"ms-2 p-3\"\r\n [class.disabled]=\"!(calendar?.selectedDates?.start && calendar?.selectedDates?.end)\"\r\n (click)=\"updateCustomRange(dateInput,calendar.selectedDates);\"> Apply </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<ng-template #dateOptionList let-options let-input=\"dateInput\" let-optionId=\"optionId\" let-className=\"className\">\r\n <mat-action-list [ngClass]=\"className\" [id]=\"optionId\">\r\n @for (option of options; track option.optionLabel) {\r\n <mat-list-item [activated]=\"option.isSelected\" (click)=\"updateSelection(option, input)\">\r\n {{option.optionLabel}}\r\n </mat-list-item>\r\n }\r\n </mat-action-list>\r\n</ng-template>\r\n", styles: ["::ng-deep .cdk-overlay-dark-backdrop{background:none}mat-list-item{height:35px}::ng-deep .cdk-overlay-pane:has(.custom-ckd-container){width:100%;background-color:var(--bg-color, white);max-height:100vh;overflow-y:auto;overflow-x:hidden;max-width:700px;margin-top:-22px;border:1px solid var(--border-color, #ddd)}::ng-deep .cdk-overlay-pane:has(.range-input){max-width:250px}.br-top{border-top:1px solid var(--border-color, #ddd)}.br-right{border-right:1px solid var(--border-color, #ddd)}.disabled{pointer-events:none;opacity:.5}.mat-button,.mdc-button{font-family:var(--mdc-list-list-item-label-text-font);line-height:var(--mdc-list-list-item-label-text-line-height);font-size:var(--mdc-list-list-item-label-text-size);font-weight:var(--mdc-list-list-item-label-text-weight);letter-spacing:var(--mdc-list-list-item-label-text-tracking)}.w-full{width:100%}.display-hidden{display:none}.custom-calendar-container,.row-1,.row-2{width:100%;display:block;float:left}.row-2{padding:.7rem}.footer-content{width:100%;align-items:center;display:flex;text-align:right;justify-content:end;gap:10px;margin-right:2rem;text-overflow:ellipsis}.buttons{margin-right:1.5rem;display:flex;gap:10px}.column-1{width:25%;display:block;float:left}.column-2{width:73%;display:block;float:left}@media (max-width: 400px){.footer-content{display:block}#range-label-text{margin-right:1.5rem}.buttons{float:right;margin-top:20px}}@media (max-width: 650px){.column-1,.column-2{width:100%}}@media (min-width: 650px){.column-1{width:25%}.column-2{width:74%}}.without-default-opt .column-1{display:none}.without-default-opt .column-2{width:100%;display:block;float:left}.pe-0{padding-right:0}.ps-0{padding-left:0}\n"], dependencies: [{ kind: "directive", type: i1$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.MatInput, selector: "input[matInput], textarea[matInput], select[matNativeControl], input[matNativeControl], textarea[matNativeControl]", inputs: ["disabled", "id", "placeholder", "name", "required", "type", "errorStateMatcher", "aria-describedby", "value", "readonly"], exportAs: ["matInput"] }, { kind: "component", type: i3.MatFormField, selector: "mat-form-field", inputs: ["hideRequiredMarker", "color", "floatLabel", "appearance", "subscriptSizing", "hintLabel"], exportAs: ["matFormField"] }, { kind: "directive", type: i3.MatLabel, selector: "mat-label" }, { kind: "directive", type: i3.MatSuffix, selector: "[matSuffix], [matIconSuffix], [matTextSuffix]", inputs: ["matTextSuffix"] }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush", "cdkConnectedOverlayDisposeOnNavigation"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i5.MatIcon, selector: "mat-icon", inputs: ["color", "inline", "svgIcon", "fontSet", "fontIcon"], exportAs: ["matIcon"] }, { kind: "component", type: i6.MatButton, selector: " button[mat-button], button[mat-raised-button], button[mat-flat-button], button[mat-stroked-button] ", exportAs: ["matButton"] }, { kind: "component", type: i6.MatIconButton, selector: "button[mat-icon-button]", exportAs: ["matButton"] }, { kind: "component", type: i7.MatActionList, selector: "mat-action-list", exportAs: ["matActionList"] }, { kind: "component", type: i7.MatListItem, selector: "mat-list-item, a[mat-list-item], button[mat-list-item]", inputs: ["activated"], exportAs: ["matListItem"] }, { kind: "directive", type: i8.MatTooltip, selector: "[matTooltip]", inputs: ["matTooltipPosition", "matTooltipPositionAtOrigin", "matTooltipDisabled", "matTooltipShowDelay", "matTooltipHideDelay", "matTooltipTouchGestures", "matTooltip", "matTooltipClass"], exportAs: ["matTooltip"] }, { kind: "component", type: CalendarComponent, selector: "lib-calendar", inputs: ["minDate", "maxDate", "selectedDates"] }, { kind: "pipe", type: i1$1.DatePipe, name: "date" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.0.6", ngImport: i0, type: NgDatePickerComponent, decorators: [{
type: Component,
args: [{ selector: 'ng-date-range-picker', changeDetection: ChangeDetectionStrategy.OnPush, template: "<!--**\r\n * @(#)ng-date-picker.component.html Sept 05, 2023\r\n\r\n * @author Aakash Kumar\r\n *-->\r\n<div class=\"date-picker-main\" cdkOverlayOrigin #trigger>\r\n <mat-form-field class=\"w-full\" [class]=\"{'display-hidden':isShowStaticDefaultOptions}\" (click)=\"toggleDateOptionSelectionList($event)\">\r\n <mat-label (click)=\"toggleDateOptionSelectionList($event)\">{{inputLabel}}</mat-label>\r\n <input matInput readonly=\"readonly\" #dateInput class=\"cursor-pointer\" id=\"date-input-field\">\r\n <button mat-icon-button matSuffix class=\"cursor-pointer pe-0 ps-0\" matTooltip=\"Clear\" *ngIf=\"!!dateInput.value\"\r\n (click)=\"clearSelection($event)\"><mat-icon>clear</mat-icon></button>\r\n <button mat-icon-button matSuffix class=\"cursor-pointer\"> <mat-icon>date_range</mat-icon></button>\r\n </mat-form-field>\r\n\r\n @if(dateDropDownOptions.length && isShowStaticDefaultOptions) {\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput,\r\n optionId: staticOptionId, className:'w-full custom-ckd-container range-input'\r\n }\"></ng-container>\r\n }\r\n\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayHasBackdrop]=\"false\" [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isDateOptionList\" [cdkConnectedOverlayPush]=\"cdkConnectedOverlayPush\"\r\n [cdkConnectedOverlayOffsetX]=\"listCdkConnectedOverlayOffsetX\" [cdkConnectedOverlayOffsetY]=\"listCdkConnectedOverlayOffsetY\"\r\n (overlayOutsideClick)=\"!isShowStaticDefaultOptions && toggleDateOptionSelectionList()\">\r\n\r\n @if(dateDropDownOptions.length && !isShowStaticDefaultOptions) {\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput,\r\n optionId: dynamicOptionId, className:'w-full custom-ckd-container range-input'\r\n }\"></ng-container>\r\n }\r\n </ng-template>\r\n\r\n <ng-template cdkConnectedOverlay [cdkConnectedOverlayHasBackdrop]=\"false\" [cdkConnectedOverlayOrigin]=\"trigger\"\r\n [cdkConnectedOverlayOpen]=\"isCustomRange\" [cdkConnectedOverlayPush]=\"cdkConnectedOverlayPush\"\r\n [cdkConnectedOverlayPositions]=\"cdkConnectedOverlayPositions\" [cdkConnectedOverlayOffsetX]=\"cdkConnectedOverlayOffsetX\"\r\n [cdkConnectedOverlayOffsetY]=\"cdkConnectedOverlayOffsetY\" (overlayOutsideClick)=\"toggleCustomDateRangeView()\">\r\n <div class=\"custom-ckd-container custom-calendar-container\" [class]=\"{'without-default-opt':hideDefaultOptions}\">\r\n <div class=\"row-1\">\r\n <div class=\"pt-custom br-right column-1\" *ngIf=\"!hideDefaultOptions\">\r\n <ng-container *ngTemplateOutlet=\"dateOptionList; context: { $implicit: visibleOptions(), dateInput: dateInput}\"></ng-container>\r\n </div>\r\n <div class=\"mt-2 column-2\"><lib-calendar [selectedDates]=\"selectedDates\" #calendar [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"></lib-calendar></div>\r\n </div>\r\n <div class=\"row-2 br-top\">\r\n <div class=\"text-end my-2 w-full\">\r\n <div class=\"footer-content\">\r\n <span id=\"range-label-text\">\r\n {{calendar?.selectedDates?.start | date: dateFormat}}\r\n @if (calendar?.selectedDates?.end) {\r\n <span> - {{calendar.selectedDates?.end | date:\r\n dateFormat}} </span>\r\n }\r\n </span>\r\n <div class=\"d-inline buttons\">\r\n <button mat-button mat-raised-button class=\"p-3 mx-2\" (click)=\"isCustomRange=false;\">Cancel</button>\r\n <button mat-button mat-raised-button color=\"primary\" class=\"ms-2 p-3\"\r\n [class.disabled]=\"!(calendar?.selectedDates?.start && calendar?.selectedDates?.end)\"\r\n (click)=\"updateCustomRange(dateInput,calendar.selectedDates);\"> Apply </button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n</div>\r\n\r\n<ng-template #dateOptionList let-options let-input=\"dateInput\" let-optionId=\"optionId\" let-className=\"className\">\r\n <mat-action-list [ngClass]=\"className\" [id]=\"optionId\">\r\n @for (option of options; track option.optionLabel) {\r\n <mat-list-item [activated]=\"option.isSelected\" (click)=\"updateSelection(option, input)\">\r\n {{option.optionLabel}}\r\n </mat-list-item>\r\n }\r\n </mat-action-list>\r\n</ng-template>\r\n", styles: ["::ng-deep .cdk-overlay-dark-backdrop{background:none}mat-list-item{height:35px}::ng-deep .cdk-overlay-pane:has(.custom-ckd-container){width:100%;background-color:var(--bg-color, white);max-height:100vh;overflow-y:auto;overflow-x:hidden;max-width:700px;margin-top:-22px;border:1px solid var(--border-color, #ddd)}::ng-deep .cdk-overlay-pane:has(.range-input){max-width:250px}.br-top{border-top:1px solid var(--border-color, #ddd)}.br-right{border-right:1px solid var(--border-color, #ddd)}.disabled{pointer-events:none;opacity:.5}.mat-button,.mdc-button{font-family:var(--mdc-list-list-item-label-text-font);line-height:var(--mdc-list-list-item-label-text-line-height);font-size:var(--mdc-list-list-item-label-text-size);font-weight:var(--mdc-list-list-item-label-text-weight);letter-spacing:var(--mdc-list-list-item-label-text-tracking)}.w-full{width:100%}.display-hidden{display:none}.custom-calendar-container,.row-1,.row-2{width:100%;display:block;float:left}.row-2{padding:.7rem}.footer-content{width:100%;align-items:center;display:flex;text-align:right;justify-content:end;gap:10px;margin-right:2rem;text-overflow:ellipsis}.buttons{margin-right:1.5rem;display:flex;gap:10px}.column-1{width:25%;display:block;float:left}.column-2{width:73%;display:block;float:left}@media (max-width: 400px){.footer-content{display:block}#range-label-text{margin-right:1.5rem}.buttons{float:right;margin-top:20px}}@media (max-width: 650px){.column-1,.column-2{width:100%}}@media (min-width: 650px){.column-1{width:25%}.column-2{width:74%}}.without-default-opt .column-1{display:none}.without-default-opt .column-2{width:100%;display:block;float:left}.pe-0{padding-right:0}.ps-0{padding-left:0}\n"] }]
}], ctorParameters: () => [], propDecorators: { inputLabel: [{
type: Input
}], staticOptionId: [{
type: Input
}], dynamicOptionId: [{
type: Input
}], calendarId: [{
type: Input
}], enableDefaultOptions: [{
type: Input
}], selectedDates: [{
type: Input
}], dateFormat: [{
type: Input
}], isShowStaticDefaultOptions: [{
type: Input
}], hideDefaultOptions: [{
type: Input
}], cdkConnectedOverlayOffsetX: [{
type: Input
}], cdkConnectedOverlayOffsetY: [{
type: Input
}], listCdkConnectedOverlayOffsetY: [{
type: Input
}], listCdkConnectedOverlayOffsetX: [{
type: Input
}], selectedOptionIndex: [{
type: Input
}], displaySelectedLabel: [{
type: Input
}], cdkConnectedOverlayPush: [{
type: Input
}], cdkConnectedOverlayPositions: [{
type: Input
}], minDate: [{
type: Input
}], maxDate: [{
type: Input
}], onDateSelectionChanged: [{
type: Output
}], dateListOptions: [{
type: Output
}], dateDropDownOptions: [{
type: Input
}] } });
/**
* Default implementation of a selectable date opt