UNPKG

ng-material-date-range-picker

Version:
1 lines 64.2 kB
{"version":3,"file":"ng-material-date-range-picker.mjs","sources":["../../../projects/ng-date-picker/src/lib/constant/date-filter-const.ts","../../../projects/ng-date-picker/src/lib/utils/date-picker-utilities.ts","../../../projects/ng-date-picker/src/lib/data/default-date-options.ts","../../../projects/ng-date-picker/src/lib/calendar/calendar.component.ts","../../../projects/ng-date-picker/src/lib/calendar/calendar.component.html","../../../projects/ng-date-picker/src/lib/ng-date-picker.component.ts","../../../projects/ng-date-picker/src/lib/ng-date-picker.component.html","../../../projects/ng-date-picker/src/lib/model/select-date-option.model.ts","../../../projects/ng-date-picker/src/lib/ng-date-picker.module.ts","../../../projects/ng-date-picker/src/public-api.ts","../../../projects/ng-date-picker/src/ng-material-date-range-picker.ts"],"sourcesContent":["/**\r\n * @(#)date-filter-enum.ts Sept 08, 2023\r\n *\r\n * @author Aakash Kumar\r\n */\r\nexport const ACTIVE_DATE_DEBOUNCE = 100;\r\n\r\nexport enum DATE_OPTION_TYPE {\r\n DATE_DIFF = 1,\r\n LAST_MONTH = 2,\r\n THIS_MONTH = 3,\r\n YEAR_TO_DATE = 4,\r\n CUSTOM = 5,\r\n MONTH_TO_DATE = 6,\r\n WEEK_TO_DATE = 7,\r\n}\r\n","import { DateRange, MatCalendar } from '@angular/material/datepicker';\r\nimport { DatePipe } from '@angular/common';\r\nimport { DATE_OPTION_TYPE } from '../constant/date-filter-const';\r\nimport { ISelectDateOption } from '../model/select-date-option.model';\r\nimport { ChangeDetectorRef } from '@angular/core';\r\nimport { ActiveDate } from '../model/active-date.model';\r\n\r\n/**\r\n * Resets the selection state for all options\r\n * and marks the given option as selected if provided.\r\n *\r\n * @param options - List of date options\r\n * @param selectedOption - Option to be marked as selected\r\n */\r\nexport function resetOptionSelection(\r\n options: ISelectDateOption[],\r\n selectedOption?: ISelectDateOption\r\n) {\r\n options.forEach((option) => (option.isSelected = false));\r\n if (selectedOption) {\r\n selectedOption.isSelected = true;\r\n }\r\n}\r\n\r\n/**\r\n * Marks the custom date option as selected.\r\n *\r\n * @param options - List of date options\r\n */\r\nexport function selectCustomOption(options: ISelectDateOption[]): void {\r\n const customOption = options.find(\r\n (option) => option.optionType === DATE_OPTION_TYPE.CUSTOM\r\n );\r\n if (customOption) customOption.isSelected = true;\r\n}\r\n\r\n/**\r\n * Returns a new date with the given year offset applied.\r\n *\r\n * @param offset - Number of years to add (negative for past years)\r\n * @returns Date object with updated year\r\n */\r\nexport function getDateWithOffset(offset: number) {\r\n const date = new Date();\r\n date.setFullYear(date.getFullYear() + offset);\r\n return date;\r\n}\r\n\r\n/**\r\n * Creates a deep clone of the provided object or array.\r\n *\r\n * @param data - Data to be cloned\r\n * @returns A deep copy of the data\r\n */\r\nexport function getClone<T>(data: T): T {\r\n return JSON.parse(JSON.stringify(data));\r\n}\r\n\r\n/**\r\n * Formats a date object into a string using Angular DatePipe.\r\n *\r\n * @param date - Date to be formatted\r\n * @param dateFormat - Desired date format (e.g., 'dd/MM/yyyy')\r\n * @returns Formatted date string\r\n */\r\nexport function getDateString(date: Date, dateFormat: string): string {\r\n const datePipe = new DatePipe('en');\r\n return datePipe.transform(date, dateFormat) ?? '';\r\n}\r\n\r\n/**\r\n * Formats a date range into a string with start and end dates.\r\n *\r\n * @param range - Date range with start and end\r\n * @param dateFormat - Desired date format\r\n * @returns Formatted range string (e.g., '01/01/2023 - 07/01/2023')\r\n */\r\nexport function getFormattedDateString(\r\n range: DateRange<Date>,\r\n dateFormat: string\r\n) {\r\n if (!(range.start && range.end)) {\r\n return '';\r\n }\r\n return (\r\n getDateString(range.start, dateFormat) +\r\n ' - ' +\r\n getDateString(range.end, dateFormat)\r\n );\r\n}\r\n\r\n/**\r\n * Creates a standardized date option object for dropdowns.\r\n *\r\n * @param label - Display label for the option\r\n * @param key - Option key from DEFAULT_DATE_OPTION_ENUM\r\n * @param dateDiff - Offset in days from current date (default: 0)\r\n * @param isVisible - Whether the option is visible (default: true)\r\n * @returns ISelectDateOption object\r\n */\r\nexport function createOption(\r\n label: string,\r\n key: DATE_OPTION_TYPE,\r\n dateDiff = 0,\r\n isVisible = true\r\n): ISelectDateOption {\r\n return {\r\n optionLabel: label,\r\n optionType: key,\r\n dateDiff,\r\n isSelected: false,\r\n isVisible,\r\n };\r\n}\r\n\r\n/**\r\n * Returns the date of the next month based on the given date.\r\n *\r\n * @param currDate - Current date\r\n * @returns A new Date object incremented by one month\r\n */\r\nexport function getDateOfNextMonth(currDate: Date): Date {\r\n const date = new Date(currDate);\r\n date.setMonth(currDate.getMonth() + 1);\r\n return date;\r\n}\r\n\r\n/**\r\n * Returns the first day of the month following the given date.\r\n *\r\n * @param currDate - The current date\r\n * @returns A Date object set to the first day of the next month\r\n */\r\nexport function getFirstDateOfNextMonth(currDate: Date): Date {\r\n return new Date(currDate.getFullYear(), currDate.getMonth() + 1, 1);\r\n}\r\n\r\n/**\r\n * Returns the number of days in the month of the given date.\r\n *\r\n * @param date The date to calculate the days for.\r\n * @returns Number of days in the month.\r\n */\r\nexport function getDaysInMonth(date: Date): number {\r\n return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();\r\n}\r\n\r\n/**\r\n * Overrides the `activeDate` setter for a MatCalendar instance, injecting custom handler logic\r\n * while preserving the original setter behavior. Useful for reacting to internal date navigation\r\n * events (e.g., month changes) in Angular Material's calendar.\r\n *\r\n * @param calendar - Instance of MatCalendar whose `activeDate` setter will be overridden.\r\n * @param cdref - ChangeDetectorRef to trigger view updates after the setter runs.\r\n * @param handler - Custom callback function executed whenever `activeDate` is set.\r\n */\r\nexport function overrideActiveDateSetter(\r\n calendar: MatCalendar<Date>,\r\n cdref: ChangeDetectorRef,\r\n handler: (date: ActiveDate) => void\r\n): void {\r\n const proto = Object.getPrototypeOf(calendar);\r\n const descriptor = Object.getOwnPropertyDescriptor(proto, 'activeDate');\r\n\r\n if (!(descriptor?.set && descriptor?.get)) {\r\n console.warn(\r\n 'overrideActiveDateSetter: activeDate setter/getter not found on MatCalendar prototype.'\r\n );\r\n return;\r\n }\r\n const originalSetter = descriptor.set;\r\n const originalGetter = descriptor.get;\r\n\r\n Object.defineProperty(calendar, 'activeDate', {\r\n configurable: true,\r\n enumerable: false,\r\n get() {\r\n return originalGetter.call(this);\r\n },\r\n\r\n set(value: Date) {\r\n const activeDate: ActiveDate = {\r\n previous: originalGetter.call(this) ?? value,\r\n current: value,\r\n };\r\n originalSetter.call(this, value);\r\n handler.call(this, activeDate);\r\n cdref.markForCheck();\r\n },\r\n });\r\n}\r\n","/**\r\n * @(#)default-date-options.ts Sept 08, 2023\r\n *\r\n * @author Aakash Kumar\r\n */\r\nimport { DATE_OPTION_TYPE } from '../constant/date-filter-const';\r\nimport { ISelectDateOption } from '../model/select-date-option.model';\r\nimport { createOption } from '../utils/date-picker-utilities';\r\n\r\nexport const DEFAULT_DATE_OPTIONS: ISelectDateOption[] = <ISelectDateOption[]>[\r\n createOption('Today', DATE_OPTION_TYPE.DATE_DIFF, 0),\r\n createOption('Yesterday', DATE_OPTION_TYPE.DATE_DIFF, -1),\r\n createOption('Last 7 Days', DATE_OPTION_TYPE.DATE_DIFF, -7),\r\n createOption('Last 30 Days', DATE_OPTION_TYPE.DATE_DIFF, -30),\r\n createOption('Last Month', DATE_OPTION_TYPE.LAST_MONTH),\r\n createOption('This Month', DATE_OPTION_TYPE.THIS_MONTH),\r\n createOption('Month To Date', DATE_OPTION_TYPE.MONTH_TO_DATE),\r\n createOption('Week To Date', DATE_OPTION_TYPE.WEEK_TO_DATE, 0, false),\r\n createOption('Year To Date', DATE_OPTION_TYPE.YEAR_TO_DATE),\r\n createOption('Custom Range', DATE_OPTION_TYPE.CUSTOM),\r\n];\r\n","/**\r\n * @(#)calendar.component.scss Sept 07, 2023\r\n *\r\n * Custom Calendar Component that manages two side-by-side\r\n * month views with support for date range selection, hover\r\n * highlighting, and navigation controls.\r\n *\r\n * @author Aakash Kumar\r\n */\r\nimport {\r\n AfterViewInit,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n ElementRef,\r\n inject,\r\n Input,\r\n Renderer2,\r\n signal,\r\n ViewChild,\r\n} from '@angular/core';\r\nimport { DateRange, MatCalendar } from '@angular/material/datepicker';\r\nimport { ActiveDate } from '../model/active-date.model';\r\nimport {\r\n getDateOfNextMonth,\r\n getFirstDateOfNextMonth,\r\n overrideActiveDateSetter,\r\n} from '../utils/date-picker-utilities';\r\nimport { ACTIVE_DATE_DEBOUNCE } from '../constant/date-filter-const';\r\n\r\n@Component({\r\n selector: 'lib-calendar',\r\n templateUrl: './calendar.component.html',\r\n styleUrls: ['./calendar.component.css'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class CalendarComponent implements AfterViewInit {\r\n firstViewStartDate = signal(new Date());\r\n secondViewStartDate = signal(getDateOfNextMonth(this.firstViewStartDate()));\r\n secondViewMinDate = signal(\r\n getFirstDateOfNextMonth(this.firstViewStartDate())\r\n );\r\n\r\n @Input() minDate!: Date;\r\n @Input() maxDate!: Date;\r\n\r\n @ViewChild('firstCalendarView') firstCalendarView!: MatCalendar<Date>;\r\n @ViewChild('secondCalendarView') secondCalendarView!: MatCalendar<Date>;\r\n\r\n private _selectedDates!: DateRange<Date> | null;\r\n private isAllowHoverEvent: boolean = false;\r\n private cdref = inject(ChangeDetectorRef);\r\n private el = inject(ElementRef);\r\n private renderer = inject(Renderer2);\r\n\r\n /**\r\n * Updates the selected date range and synchronizes both calendar views.\r\n */\r\n @Input()\r\n set selectedDates(selectedDates: DateRange<Date> | null) {\r\n this._selectedDates = selectedDates;\r\n if (!selectedDates || !(selectedDates.start && selectedDates.end)) return;\r\n\r\n const startDate = selectedDates.start ?? new Date();\r\n const endDate = selectedDates.end;\r\n this.firstViewStartDate.set(startDate);\r\n this.secondViewMinDate.set(getFirstDateOfNextMonth(startDate));\r\n const computedEndDate =\r\n startDate.getMonth() === endDate.getMonth()\r\n ? getDateOfNextMonth(endDate)\r\n : endDate;\r\n this.secondViewStartDate.set(computedEndDate);\r\n }\r\n\r\n get selectedDates() {\r\n return this._selectedDates;\r\n }\r\n\r\n /**\r\n * Lifecycle hook that is called after Angular has fully initialized\r\n * the component's view (and child views).\r\n *\r\n * Used here to attach hover events and register active date change\r\n * listeners once the calendar views are available in the DOM.\r\n */\r\n ngAfterViewInit(): void {\r\n this.attachHoverEvent('firstCalendarView');\r\n this.attachHoverEvent('secondCalendarView');\r\n this.registerActiveDateChangeEvents();\r\n }\r\n\r\n /**\r\n * Handles month selection in the first view.\r\n *\r\n * @param event - Selected month date\r\n */\r\n monthSelected(viewName: string) {\r\n if (viewName === 'secondCalendarView') {\r\n this.removeDefaultFocus(this);\r\n }\r\n this.attachHoverEvent(viewName);\r\n }\r\n\r\n /**\r\n * Updates the selected date range when a date is clicked.\r\n *\r\n * @param date - Date clicked by the user\r\n */\r\n updateDateRangeSelection(date: Date | null): void {\r\n const selectedDates = this.selectedDates;\r\n if (\r\n !selectedDates ||\r\n (selectedDates.start && selectedDates.end) ||\r\n (selectedDates.start && date && selectedDates.start > date)\r\n ) {\r\n this._selectedDates = new DateRange<Date>(date, null);\r\n this.isAllowHoverEvent = true;\r\n } else {\r\n this.isAllowHoverEvent = false;\r\n this._selectedDates = new DateRange<Date>(selectedDates.start, date);\r\n }\r\n this.cdref.markForCheck();\r\n }\r\n\r\n /**\r\n * Registers event handlers for active date changes on both calendar views.\r\n *\r\n * This method overrides the default `activeDate` property setter of each\r\n * calendar view to ensure custom handlers are executed whenever the\r\n * active date changes.\r\n */\r\n private registerActiveDateChangeEvents(): void {\r\n overrideActiveDateSetter(\r\n this.firstCalendarView,\r\n this.cdref,\r\n this.onFirstViewActiveDateChange.bind(this)\r\n );\r\n overrideActiveDateSetter(\r\n this.secondCalendarView,\r\n this.cdref,\r\n this.onSecondViewActiveDateChange.bind(this)\r\n );\r\n }\r\n\r\n /**\r\n * Handles the event when the active date of the first calendar view changes.\r\n *\r\n * @param activeDate - Object containing `previous` and `current` date values.\r\n */\r\n private onFirstViewActiveDateChange(activeDate: ActiveDate): void {\r\n const handler = this.isPrevious(activeDate)\r\n ? () => this.handleFirstViewPrevEvent(activeDate)\r\n : () => this.handleFirstViewNextEvent(activeDate.current);\r\n\r\n // Delay execution because active date event fires before view update\r\n setTimeout(handler, ACTIVE_DATE_DEBOUNCE);\r\n }\r\n\r\n /**\r\n * Handles the event when the active date of the second calendar view changes.\r\n *\r\n * @param activeDate - Object containing `previous` and `current` date values.\r\n */\r\n private onSecondViewActiveDateChange(activeDate: ActiveDate): void {\r\n this.attachHoverEvent('secondCalendarView');\r\n }\r\n\r\n /**\r\n * Handles the \"next\" navigation event for the first calendar view.\r\n *\r\n * @param currDate - The currently active date in the first calendar view.\r\n * @param force - Optional flag that can be used to enforce updates (not used in current logic).\r\n */\r\n private handleFirstViewNextEvent(currDate: Date, force?: boolean): void {\r\n if (this.firstCalendarView.currentView.toLocaleLowerCase() !== 'month') {\r\n return;\r\n }\r\n this.attachHoverEvent('firstCalendarView');\r\n const nextMonthDate = getFirstDateOfNextMonth(currDate);\r\n let secondViewActiveDate = this.secondCalendarView.activeDate;\r\n if (nextMonthDate < secondViewActiveDate) {\r\n this.secondViewMinDate.set(nextMonthDate);\r\n this.attachHoverEvent('secondCalendarView');\r\n return;\r\n }\r\n secondViewActiveDate = getDateOfNextMonth(currDate);\r\n this.secondViewMinDate.set(nextMonthDate);\r\n this.secondCalendarView.activeDate = secondViewActiveDate;\r\n this.cdref.detectChanges();\r\n }\r\n\r\n /**\r\n * Handles the \"previous\" navigation event for the first calendar view.\r\n *\r\n * @param activeDate - Object containing `previous` and `current` date values.\r\n */\r\n private handleFirstViewPrevEvent(activeDate: ActiveDate): void {\r\n if (this.firstCalendarView.currentView.toLocaleLowerCase() !== 'month') {\r\n return;\r\n }\r\n this.secondViewMinDate.set(getFirstDateOfNextMonth(activeDate.current));\r\n this.attachHoverEvent('firstCalendarView');\r\n this.attachHoverEvent('secondCalendarView');\r\n }\r\n\r\n /**\r\n * Checks whether the previous date is greater than the current date.\r\n *\r\n * @param activeDate - Object containing `previous` and `current` date values.\r\n * @returns `true` if the previous date is later than the current date, otherwise `false`.\r\n */\r\n private isPrevious(activeDate: ActiveDate): boolean {\r\n return activeDate.previous > activeDate.current;\r\n }\r\n\r\n /**\r\n * Attaches hover events to all date cells in the first view.\r\n */\r\n private attachHoverEvent(viewId: string) {\r\n const nodes = this.el.nativeElement.querySelectorAll(\r\n `#${viewId} .mat-calendar-body-cell`\r\n );\r\n setTimeout(() => this.addHoverEvents(nodes), ACTIVE_DATE_DEBOUNCE);\r\n }\r\n\r\n /**\r\n * Removes active focus from the second view.\r\n *\r\n * @param classRef - Reference to this component\r\n */\r\n private removeDefaultFocus(classRef: CalendarComponent): void {\r\n setTimeout(() => {\r\n const btn: HTMLButtonElement[] =\r\n classRef.el.nativeElement.querySelectorAll(\r\n '#secondCalendarView button.mat-calendar-body-active'\r\n );\r\n if (btn?.length) {\r\n btn[0].blur();\r\n }\r\n }, 1);\r\n }\r\n\r\n /**\r\n * Updates the selection range dynamically on hover.\r\n *\r\n * @param date - Hovered date\r\n */\r\n private updateSelectionOnMouseHover(date: Date): void {\r\n const selectedDates = this.selectedDates;\r\n if (selectedDates?.start && date && selectedDates.start < date) {\r\n const dateRange: DateRange<Date> = new DateRange<Date>(\r\n selectedDates.start,\r\n date\r\n );\r\n this.firstCalendarView.selected = dateRange;\r\n this.secondCalendarView.selected = dateRange;\r\n this.firstCalendarView['_changeDetectorRef'].markForCheck();\r\n this.secondCalendarView['_changeDetectorRef'].markForCheck();\r\n this.isAllowHoverEvent = true;\r\n }\r\n }\r\n\r\n /**\r\n * Attaches hover events to given nodes to update range selection.\r\n *\r\n * @param nodes - Date cell nodes\r\n */\r\n private addHoverEvents(nodes: any): void {\r\n if (!nodes) {\r\n return;\r\n }\r\n Array.from(nodes).forEach((button) => {\r\n this.renderer.listen(button, 'mouseover', (event) => {\r\n if (this.isAllowHoverEvent) {\r\n const date = new Date(event.target['ariaLabel']);\r\n this.updateSelectionOnMouseHover(date);\r\n }\r\n });\r\n });\r\n this.firstCalendarView['_changeDetectorRef'].markForCheck();\r\n this.secondCalendarView['_changeDetectorRef'].markForCheck();\r\n }\r\n}\r\n","<!--**\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","/**\r\n * @(#)ng-date-picker.component.ts Sept 05, 2023\r\n *\r\n * @author Aakash Kumar\r\n */\r\nimport {\r\n AfterViewInit,\r\n ChangeDetectionStrategy,\r\n ChangeDetectorRef,\r\n Component,\r\n computed,\r\n ElementRef,\r\n EventEmitter,\r\n inject,\r\n Input,\r\n OnInit,\r\n Output,\r\n Signal,\r\n signal,\r\n WritableSignal,\r\n} from '@angular/core';\r\nimport { DateRange } from '@angular/material/datepicker';\r\nimport { SelectedDateEvent } from '../public-api';\r\nimport { DATE_OPTION_TYPE } from './constant/date-filter-const';\r\nimport { DEFAULT_DATE_OPTIONS } from './data/default-date-options';\r\nimport { ISelectDateOption } from './model/select-date-option.model';\r\nimport {\r\n getClone,\r\n getDateString,\r\n getDateWithOffset,\r\n getDaysInMonth,\r\n getFormattedDateString,\r\n resetOptionSelection,\r\n selectCustomOption,\r\n} from './utils/date-picker-utilities';\r\n\r\n@Component({\r\n selector: 'ng-date-range-picker',\r\n templateUrl: './ng-date-picker.component.html',\r\n styleUrls: ['./ng-date-picker.component.scss'],\r\n changeDetection: ChangeDetectionStrategy.OnPush,\r\n})\r\nexport class NgDatePickerComponent implements OnInit, AfterViewInit {\r\n public isDateOptionList: boolean = false;\r\n public isCustomRange: boolean = false;\r\n @Input() inputLabel: string = 'Date Range';\r\n @Input() staticOptionId = 'static-options';\r\n @Input() dynamicOptionId = 'dynamic-options';\r\n @Input() calendarId: string = 'custom-calendar';\r\n @Input() enableDefaultOptions: boolean = true;\r\n @Input() selectedDates!: DateRange<Date> | null;\r\n @Input() dateFormat: string = 'dd/MM/yyyy';\r\n @Input() isShowStaticDefaultOptions: boolean = false;\r\n @Input() hideDefaultOptions: boolean = false;\r\n @Input() cdkConnectedOverlayOffsetX = 0;\r\n @Input() cdkConnectedOverlayOffsetY = 0;\r\n @Input() listCdkConnectedOverlayOffsetY = 0;\r\n @Input() listCdkConnectedOverlayOffsetX = 0;\r\n @Input() selectedOptionIndex = 3;\r\n @Input() displaySelectedLabel = false;\r\n @Input() cdkConnectedOverlayPush = true;\r\n @Input() cdkConnectedOverlayPositions = [];\r\n\r\n // default min date is current date - 10 years.\r\n @Input() minDate = getDateWithOffset(-10);\r\n // default max date is current date + 10 years.\r\n @Input() maxDate = getDateWithOffset(10);\r\n\r\n @Output() onDateSelectionChanged = new EventEmitter<SelectedDateEvent>();\r\n @Output() dateListOptions = new EventEmitter<ISelectDateOption[]>();\r\n\r\n private cdref: ChangeDetectorRef = inject(ChangeDetectorRef);\r\n private el: ElementRef = inject(ElementRef);\r\n\r\n private _dateOptions: WritableSignal<ISelectDateOption[]> = signal([]);\r\n visibleOptions = computed(() =>\r\n this._dateOptions().filter((op) => op.isVisible)\r\n );\r\n constructor() {}\r\n\r\n @Input()\r\n set dateDropDownOptions(defaultDateList: ISelectDateOption[]) {\r\n const options = [\r\n ...(this.enableDefaultOptions ? getClone(DEFAULT_DATE_OPTIONS) : []),\r\n ...(defaultDateList ?? []),\r\n ];\r\n this._dateOptions.set(options);\r\n }\r\n\r\n get dateDropDownOptions(): ISelectDateOption[] {\r\n return this._dateOptions() ?? [];\r\n }\r\n\r\n ngOnInit(): void {\r\n if (this.isDefaultInitRequired()) {\r\n this.initDefaultOptions();\r\n }\r\n this.dateListOptions.emit(this.dateDropDownOptions);\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n this.updateDefaultDatesValues();\r\n }\r\n\r\n /**\r\n * Toggles the visibility of the default date option list.\r\n * If the custom option is selected, toggles the custom date range view instead.\r\n *\r\n * @param event Optional MouseEvent triggering the toggle.\r\n */\r\n toggleDateOptionSelectionList(event?: MouseEvent): void {\r\n event?.preventDefault();\r\n event?.stopImmediatePropagation();\r\n const isCustomSelected =\r\n this.dateDropDownOptions.find((option) => option.isSelected)\r\n ?.optionType === DATE_OPTION_TYPE.CUSTOM;\r\n\r\n if (isCustomSelected) {\r\n this.toggleCustomDateRangeView();\r\n return;\r\n }\r\n this.isDateOptionList = !this.isDateOptionList;\r\n }\r\n\r\n /**\r\n * Updates the custom date range selection from the input.\r\n *\r\n * @param input The HTML input element associated with the date picker.\r\n * @param selectedDates The selected date range.\r\n */\r\n updateCustomRange(\r\n input: HTMLInputElement,\r\n selectedDates: DateRange<Date> | null\r\n ): void {\r\n\r\n if (this.isCustomRange) {\r\n resetOptionSelection(this.dateDropDownOptions);\r\n selectCustomOption(this.dateDropDownOptions);\r\n this.isCustomRange = false;\r\n }\r\n\r\n const start = selectedDates?.start ?? new Date();\r\n const end = selectedDates?.end ?? new Date();\r\n this.updateSelectedDates(input, start, end, null);\r\n }\r\n\r\n /**\r\n * Updates the selection when a specific date option is clicked.\r\n *\r\n * @param option The selected date option.\r\n * @param input The HTML input element to update with selected dates.\r\n */\r\n updateSelection(option: ISelectDateOption, input: HTMLInputElement): void {\r\n this.isDateOptionList = false;\r\n this.isCustomRange = option.optionType === DATE_OPTION_TYPE.CUSTOM;\r\n if (!this.isCustomRange) {\r\n resetOptionSelection(this.dateDropDownOptions, option);\r\n this.updateDateOnOptionSelect(option, input);\r\n }\r\n this.cdref.markForCheck();\r\n }\r\n\r\n /**\r\n * Toggles the custom date range selection view visibility.\r\n */\r\n toggleCustomDateRangeView(): void {\r\n this.isCustomRange = !this.isCustomRange;\r\n }\r\n\r\n /**\r\n * Clears the currently selected dates and resets all related properties.\r\n *\r\n * @param event The MouseEvent triggering the clear action.\r\n */\r\n clearSelection(event: MouseEvent): void {\r\n event?.stopImmediatePropagation();\r\n this.minDate = getDateWithOffset(-10);\r\n this.maxDate = getDateWithOffset(10);\r\n this.selectedDates = null;\r\n resetOptionSelection(this.dateDropDownOptions);\r\n this.clearDateInput();\r\n this.cdref.markForCheck();\r\n const selectedDateEventData: SelectedDateEvent = {\r\n range: null,\r\n selectedOption: null,\r\n };\r\n this.onDateSelectionChanged.emit(selectedDateEventData);\r\n }\r\n\r\n /**\r\n * Clears the input field value for the date picker.\r\n */\r\n private clearDateInput(): void {\r\n const dateInputField =\r\n this.el.nativeElement.querySelector('#date-input-field');\r\n if (dateInputField) {\r\n dateInputField.value = '';\r\n }\r\n }\r\n\r\n /**\r\n * Updates selected dates based on a selected option and input element.\r\n *\r\n * @param option The selected date option.\r\n * @param input The HTML input element to update.\r\n */\r\n private updateDateOnOptionSelect(\r\n option: ISelectDateOption,\r\n input: HTMLInputElement\r\n ): void {\r\n // If there is a callback function, use it to get the date range\r\n if (option?.callBackFunction) {\r\n const dateRange: DateRange<Date> = option.callBackFunction();\r\n if (dateRange?.start && dateRange?.end) {\r\n this.updateSelectedDates(input, dateRange.start, dateRange.end, option);\r\n return;\r\n }\r\n }\r\n this.updateDateWithSelectedOption(option, input);\r\n }\r\n\r\n /**\r\n * Calculates and updates the start and end dates based on the selected option.\r\n *\r\n * @param option The selected date option.\r\n * @param input The HTML input element to update.\r\n */\r\n private updateDateWithSelectedOption(\r\n option: ISelectDateOption,\r\n input: HTMLInputElement\r\n ): void {\r\n const currDate = new Date();\r\n let startDate: Date = new Date();\r\n let lastDate: Date = new Date();\r\n // Determine the date range based on the option key\r\n switch (option.optionType) {\r\n case DATE_OPTION_TYPE.DATE_DIFF:\r\n startDate.setDate(startDate.getDate() + (option.dateDiff ?? 0));\r\n break;\r\n\r\n case DATE_OPTION_TYPE.LAST_MONTH:\r\n currDate.setMonth(currDate.getMonth() - 1);\r\n startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);\r\n lastDate = new Date(\r\n currDate.getFullYear(),\r\n currDate.getMonth(),\r\n getDaysInMonth(currDate)\r\n );\r\n break;\r\n\r\n case DATE_OPTION_TYPE.THIS_MONTH:\r\n startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);\r\n lastDate = new Date(\r\n currDate.getFullYear(),\r\n currDate.getMonth(),\r\n getDaysInMonth(currDate)\r\n );\r\n break;\r\n\r\n case DATE_OPTION_TYPE.YEAR_TO_DATE:\r\n startDate = new Date(currDate.getFullYear(), 0, 1);\r\n break;\r\n\r\n case DATE_OPTION_TYPE.MONTH_TO_DATE:\r\n startDate = new Date(currDate.getFullYear(), currDate.getMonth(), 1);\r\n break;\r\n\r\n default:\r\n break;\r\n }\r\n\r\n // Update the selected dates\r\n this.updateSelectedDates(input, startDate, lastDate, option);\r\n }\r\n\r\n /**\r\n * Updates the date range and input display.\r\n *\r\n * @param input The HTML input element.\r\n * @param start Start date of the range.\r\n * @param end End date of the range.\r\n * @param opt Optional selected date option.\r\n */\r\n private updateSelectedDates(\r\n input: HTMLInputElement,\r\n start: Date,\r\n end: Date,\r\n opt: ISelectDateOption | null\r\n ): void {\r\n const range = new DateRange(start, end);\r\n this.selectedDates = range;\r\n\r\n const label = this.displaySelectedLabel ? opt?.optionLabel : null;\r\n const rangeLabel = `${getDateString(\r\n start,\r\n this.dateFormat\r\n )} - ${getDateString(end, this.dateFormat)}`;\r\n\r\n input.value = label ?? rangeLabel;\r\n this.onDateSelectionChanged.emit({\r\n range,\r\n selectedOption:\r\n this.dateDropDownOptions.find((o) => o.isSelected) ?? null,\r\n });\r\n this.cdref.markForCheck();\r\n }\r\n\r\n /**\r\n * Updates the input and internal state with default dates on initialization.\r\n */\r\n private updateDefaultDatesValues(): void {\r\n const input: HTMLInputElement =\r\n this.el.nativeElement.querySelector('#date-input-field');\r\n if (this.selectedDates?.start && this.selectedDates?.end) {\r\n this._dateOptions().find(\r\n (option) => option.optionType === DATE_OPTION_TYPE.CUSTOM\r\n )!.isSelected = true;\r\n input.value = getFormattedDateString(this.selectedDates, this.dateFormat);\r\n this.cdref.detectChanges();\r\n return;\r\n }\r\n\r\n const selectedOptions = this._dateOptions().find(\r\n (option) => option.isSelected\r\n );\r\n\r\n if (\r\n selectedOptions &&\r\n selectedOptions.optionType !== DATE_OPTION_TYPE.CUSTOM\r\n ) {\r\n this.updatedFromListValueSelection(selectedOptions, input);\r\n this.cdref.detectChanges();\r\n }\r\n }\r\n\r\n /**\r\n * Updates the input and selected dates based on a selected option from the list.\r\n *\r\n * @param selectedOption The selected date option.\r\n * @param input The HTML input element to update.\r\n */\r\n private updatedFromListValueSelection(\r\n selectedOption: ISelectDateOption,\r\n input: HTMLInputElement\r\n ): void {\r\n // This will update value if option is selected from default list.\r\n if (!selectedOption['callBackFunction']) {\r\n this.updateDateOnOptionSelect(selectedOption, input);\r\n return;\r\n }\r\n // This will update value if option is selected from provided custom list.\r\n const dateRange: DateRange<Date> = selectedOption.callBackFunction();\r\n this.updateSelectedDates(\r\n input,\r\n dateRange.start ?? new Date(),\r\n dateRange.end ?? new Date(),\r\n selectedOption\r\n );\r\n }\r\n\r\n /**\r\n * Checks whether default initialization of options is required.\r\n *\r\n * @returns True if default options need to be initialized, otherwise false.\r\n */\r\n private isDefaultInitRequired(): boolean {\r\n return this.enableDefaultOptions && !this._dateOptions.length;\r\n }\r\n\r\n /**\r\n * Initializes the default date options with the selected index.\r\n */\r\n private initDefaultOptions(): void {\r\n const options = getClone<ISelectDateOption[]>(DEFAULT_DATE_OPTIONS).map(\r\n (opt, idx) => ({\r\n ...opt,\r\n isSelected: idx === this.selectedOptionIndex,\r\n })\r\n );\r\n this._dateOptions.set(options);\r\n }\r\n}\r\n","<!--**\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);\">&nbsp;Apply&nbsp;</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","import { DateRange } from '@angular/material/datepicker';\r\nimport { DATE_OPTION_TYPE } from '../constant/date-filter-const';\r\n\r\n/**\r\n * @(#)select-date-option.ts Sept 08, 2023\r\n *\r\n * Defines the structure and behavior of a selectable date option,\r\n * used in date filtering components.\r\n *\r\n * @author Aakash Kumar\r\n */\r\nexport interface ISelectDateOption {\r\n /**\r\n * Label displayed in the drop-down list for this option.\r\n * Example: \"Last 7 Days\", \"Today\", \"Custom\".\r\n */\r\n optionLabel: string;\r\n\r\n /**\r\n * Type of the option, indicating how the date is determined.\r\n * Defaults to DATE_DIFF if not provided.\r\n */\r\n optionType?: DATE_OPTION_TYPE;\r\n\r\n /**\r\n * Number of days offset from today.\r\n *\r\n * - Positive numbers indicate future dates.\r\n * - Negative numbers indicate past dates.\r\n * - Used only when optionType is DATE_DIFF and no callback is provided.\r\n *\r\n * Example: -7 → \"Last 7 Days\"\r\n */\r\n dateDiff?: number;\r\n\r\n /**\r\n * Whether this option is currently selected.\r\n */\r\n isSelected: boolean;\r\n\r\n /**\r\n * Whether this option should be shown in the drop-down list.\r\n */\r\n isVisible: boolean;\r\n\r\n /**\r\n * Custom function to calculate and return a DateRange.\r\n * Used when optionType requires special handling beyond dateDiff.\r\n */\r\n callBackFunction?: () => DateRange<Date>;\r\n}\r\n\r\n/**\r\n * Default implementation of a selectable date option.\r\n * Provides default values for all fields.\r\n */\r\nexport class SelectDateOption implements ISelectDateOption {\r\n optionLabel = '';\r\n optionType = DATE_OPTION_TYPE.DATE_DIFF;\r\n dateDiff = 0;\r\n isSelected = false;\r\n isVisible = false;\r\n callBackFunction!: () => DateRange<Date>;\r\n}\r\n","/**\r\n * @(#)ng-date-picker.module.ts Sept 05, 2023\r\n *\r\n * @author Aakash Kumar\r\n */\r\nimport { OverlayModule } from '@angular/cdk/overlay';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NgModule } from '@angular/core';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { MatAutocompleteModule } from '@angular/material/autocomplete';\r\nimport { MatButtonModule } from '@angular/material/button';\r\nimport { MatNativeDateModule } from '@angular/material/core';\r\nimport { MatDatepickerModule } from '@angular/material/datepicker';\r\nimport { MatFormFieldModule } from '@angular/material/form-field';\r\nimport { MatIconModule } from '@angular/material/icon';\r\nimport { MatInputModule } from '@angular/material/input';\r\nimport { MatListModule } from '@angular/material/list';\r\nimport { CalendarComponent } from './calendar/calendar.component';\r\nimport { NgDatePickerComponent } from './ng-date-picker.component';\r\nimport { MatTooltipModule } from '@angular/material/tooltip';\r\n\r\n@NgModule({\r\n declarations: [NgDatePickerComponent, CalendarComponent],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n MatDatepickerModule,\r\n MatNativeDateModule,\r\n MatInputModule,\r\n MatAutocompleteModule,\r\n OverlayModule,\r\n MatIconModule,\r\n MatButtonModule,\r\n MatListModule,\r\n MatFormFieldModule,\r\n MatTooltipModule,\r\n ],\r\n exports: [NgDatePickerComponent],\r\n})\r\nexport class NgDatePickerModule {}\r\n","/**\r\n * @(#)public-api.ts Sept 05, 2023\r\n *\r\n * @author Aakash Kumar\r\n */\r\n\r\n// Public API Surface of ng-date-picker\r\nexport * from './lib/ng-date-picker.component';\r\nexport * from './lib/model/select-date-option.model';\r\nexport * from './lib/ng-date-picker.module';\r\nexport * from './lib/constant/date-filter-const';\r\nexport * from './lib/model/date-selection-event.model';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1","i9.CalendarComponent"],"mappings":"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