@rossigee/clarity-angular 18.2.1-fixed → 18.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (182) hide show
  1. package/fesm2022/clr-angular-accordion.mjs +355 -0
  2. package/fesm2022/clr-angular-accordion.mjs.map +1 -0
  3. package/fesm2022/clr-angular-button.mjs +713 -0
  4. package/fesm2022/clr-angular-button.mjs.map +1 -0
  5. package/fesm2022/clr-angular-collapsible-panel.mjs +201 -0
  6. package/fesm2022/clr-angular-collapsible-panel.mjs.map +1 -0
  7. package/fesm2022/clr-angular-data-datagrid.mjs +7635 -0
  8. package/fesm2022/clr-angular-data-datagrid.mjs.map +1 -0
  9. package/fesm2022/clr-angular-data-stack-view.mjs +442 -0
  10. package/fesm2022/clr-angular-data-stack-view.mjs.map +1 -0
  11. package/fesm2022/clr-angular-data-tree-view.mjs +1106 -0
  12. package/fesm2022/clr-angular-data-tree-view.mjs.map +1 -0
  13. package/fesm2022/clr-angular-data.mjs +40 -0
  14. package/fesm2022/clr-angular-data.mjs.map +1 -0
  15. package/fesm2022/clr-angular-emphasis-alert.mjs +624 -0
  16. package/fesm2022/clr-angular-emphasis-alert.mjs.map +1 -0
  17. package/fesm2022/clr-angular-emphasis-badge.mjs +69 -0
  18. package/fesm2022/clr-angular-emphasis-badge.mjs.map +1 -0
  19. package/fesm2022/clr-angular-emphasis-common.mjs +25 -0
  20. package/fesm2022/clr-angular-emphasis-common.mjs.map +1 -0
  21. package/fesm2022/clr-angular-emphasis-label.mjs +105 -0
  22. package/fesm2022/clr-angular-emphasis-label.mjs.map +1 -0
  23. package/fesm2022/clr-angular-emphasis.mjs +41 -0
  24. package/fesm2022/clr-angular-emphasis.mjs.map +1 -0
  25. package/fesm2022/clr-angular-forms-checkbox.mjs +270 -0
  26. package/fesm2022/clr-angular-forms-checkbox.mjs.map +1 -0
  27. package/fesm2022/clr-angular-forms-combobox.mjs +1775 -0
  28. package/fesm2022/clr-angular-forms-combobox.mjs.map +1 -0
  29. package/fesm2022/clr-angular-forms-common.mjs +1251 -0
  30. package/fesm2022/clr-angular-forms-common.mjs.map +1 -0
  31. package/fesm2022/clr-angular-forms-datalist.mjs +263 -0
  32. package/fesm2022/clr-angular-forms-datalist.mjs.map +1 -0
  33. package/fesm2022/clr-angular-forms-datepicker.mjs +3274 -0
  34. package/fesm2022/clr-angular-forms-datepicker.mjs.map +1 -0
  35. package/fesm2022/clr-angular-forms-file-input.mjs +826 -0
  36. package/fesm2022/clr-angular-forms-file-input.mjs.map +1 -0
  37. package/fesm2022/clr-angular-forms-input.mjs +153 -0
  38. package/fesm2022/clr-angular-forms-input.mjs.map +1 -0
  39. package/fesm2022/clr-angular-forms-number-input.mjs +236 -0
  40. package/fesm2022/clr-angular-forms-number-input.mjs.map +1 -0
  41. package/fesm2022/clr-angular-forms-password.mjs +233 -0
  42. package/fesm2022/clr-angular-forms-password.mjs.map +1 -0
  43. package/fesm2022/clr-angular-forms-radio.mjs +231 -0
  44. package/fesm2022/clr-angular-forms-radio.mjs.map +1 -0
  45. package/fesm2022/clr-angular-forms-range.mjs +186 -0
  46. package/fesm2022/clr-angular-forms-range.mjs.map +1 -0
  47. package/fesm2022/clr-angular-forms-select.mjs +153 -0
  48. package/fesm2022/clr-angular-forms-select.mjs.map +1 -0
  49. package/fesm2022/clr-angular-forms-textarea.mjs +136 -0
  50. package/fesm2022/clr-angular-forms-textarea.mjs.map +1 -0
  51. package/fesm2022/clr-angular-forms.mjs +100 -0
  52. package/fesm2022/clr-angular-forms.mjs.map +1 -0
  53. package/fesm2022/clr-angular-icon.mjs +7397 -0
  54. package/fesm2022/clr-angular-icon.mjs.map +1 -0
  55. package/fesm2022/clr-angular-layout-breadcrumbs.mjs +120 -0
  56. package/fesm2022/clr-angular-layout-breadcrumbs.mjs.map +1 -0
  57. package/fesm2022/clr-angular-layout-main-container.mjs +100 -0
  58. package/fesm2022/clr-angular-layout-main-container.mjs.map +1 -0
  59. package/fesm2022/clr-angular-layout-nav.mjs +582 -0
  60. package/fesm2022/clr-angular-layout-nav.mjs.map +1 -0
  61. package/fesm2022/clr-angular-layout-tabs.mjs +807 -0
  62. package/fesm2022/clr-angular-layout-tabs.mjs.map +1 -0
  63. package/fesm2022/clr-angular-layout-vertical-nav.mjs +507 -0
  64. package/fesm2022/clr-angular-layout-vertical-nav.mjs.map +1 -0
  65. package/fesm2022/clr-angular-layout.mjs +44 -0
  66. package/fesm2022/clr-angular-layout.mjs.map +1 -0
  67. package/fesm2022/clr-angular-modal.mjs +617 -0
  68. package/fesm2022/clr-angular-modal.mjs.map +1 -0
  69. package/fesm2022/clr-angular-popover-common.mjs +1082 -0
  70. package/fesm2022/clr-angular-popover-common.mjs.map +1 -0
  71. package/fesm2022/clr-angular-popover-dropdown.mjs +492 -0
  72. package/fesm2022/clr-angular-popover-dropdown.mjs.map +1 -0
  73. package/fesm2022/clr-angular-popover-signpost.mjs +494 -0
  74. package/fesm2022/clr-angular-popover-signpost.mjs.map +1 -0
  75. package/fesm2022/clr-angular-popover-tooltip.mjs +293 -0
  76. package/fesm2022/clr-angular-popover-tooltip.mjs.map +1 -0
  77. package/fesm2022/clr-angular-popover.mjs +41 -0
  78. package/fesm2022/clr-angular-popover.mjs.map +1 -0
  79. package/fesm2022/clr-angular-progress-progress-bars.mjs +217 -0
  80. package/fesm2022/clr-angular-progress-progress-bars.mjs.map +1 -0
  81. package/fesm2022/clr-angular-progress-spinner.mjs +132 -0
  82. package/fesm2022/clr-angular-progress-spinner.mjs.map +1 -0
  83. package/fesm2022/clr-angular-stepper.mjs +694 -0
  84. package/fesm2022/clr-angular-stepper.mjs.map +1 -0
  85. package/fesm2022/clr-angular-timeline.mjs +316 -0
  86. package/fesm2022/clr-angular-timeline.mjs.map +1 -0
  87. package/fesm2022/clr-angular-utils-conditional.mjs +351 -0
  88. package/fesm2022/clr-angular-utils-conditional.mjs.map +1 -0
  89. package/fesm2022/clr-angular-utils-loading.mjs +107 -0
  90. package/fesm2022/clr-angular-utils-loading.mjs.map +1 -0
  91. package/fesm2022/clr-angular-utils.mjs +2079 -0
  92. package/fesm2022/clr-angular-utils.mjs.map +1 -0
  93. package/fesm2022/clr-angular-wizard.mjs +3074 -0
  94. package/fesm2022/clr-angular-wizard.mjs.map +1 -0
  95. package/fesm2022/{rossigee-clarity-angular.mjs → clr-angular.mjs} +2 -2
  96. package/fesm2022/clr-angular.mjs.map +1 -0
  97. package/package.json +105 -103
  98. package/schematics/ng-update/index.d.ts +2 -0
  99. package/schematics/ng-update/index.js +69 -0
  100. package/schematics/ng-update/index.js.map +1 -0
  101. package/schematics/ng-update/migrations/css-migration.d.ts +6 -0
  102. package/schematics/ng-update/migrations/css-migration.js +177 -0
  103. package/schematics/ng-update/migrations/css-migration.js.map +1 -0
  104. package/schematics/ng-update/migrations/import-migration.d.ts +4 -0
  105. package/schematics/ng-update/migrations/import-migration.js +187 -0
  106. package/schematics/ng-update/migrations/import-migration.js.map +1 -0
  107. package/schematics/ng-update/migrations/template-migration.d.ts +6 -0
  108. package/schematics/ng-update/migrations/template-migration.js +261 -0
  109. package/schematics/ng-update/migrations/template-migration.js.map +1 -0
  110. package/schematics/ng-update/replacements/css-replacements.d.ts +17 -0
  111. package/schematics/ng-update/replacements/css-replacements.js +74 -0
  112. package/schematics/ng-update/replacements/css-replacements.js.map +1 -0
  113. package/schematics/ng-update/replacements/import-replacements.d.ts +13 -0
  114. package/schematics/ng-update/replacements/import-replacements.js +108 -0
  115. package/schematics/ng-update/replacements/import-replacements.js.map +1 -0
  116. package/schematics/ng-update/replacements/symbol-replacements.d.ts +12 -0
  117. package/schematics/ng-update/replacements/symbol-replacements.js +67 -0
  118. package/schematics/ng-update/replacements/symbol-replacements.js.map +1 -0
  119. package/schematics/ng-update/replacements/template-replacements.d.ts +19 -0
  120. package/schematics/ng-update/replacements/template-replacements.js +57 -0
  121. package/schematics/ng-update/replacements/template-replacements.js.map +1 -0
  122. package/schematics/ng-update/tests/test-helpers.d.ts +6 -0
  123. package/schematics/ng-update/tests/test-helpers.js +34 -0
  124. package/schematics/ng-update/tests/test-helpers.js.map +1 -0
  125. package/schematics/ng-update/utils/file-visitor.d.ts +8 -0
  126. package/schematics/ng-update/utils/file-visitor.js +44 -0
  127. package/schematics/ng-update/utils/file-visitor.js.map +1 -0
  128. package/schematics/ng-update/utils/regexp-utils.d.ts +16 -0
  129. package/schematics/ng-update/utils/regexp-utils.js +34 -0
  130. package/schematics/ng-update/utils/regexp-utils.js.map +1 -0
  131. package/schematics/vitest.config.d.ts +2 -0
  132. package/schematics/vitest.config.js +17 -0
  133. package/schematics/vitest.config.js.map +1 -0
  134. package/types/clr-angular-accordion.d.ts +100 -0
  135. package/types/clr-angular-button.d.ts +169 -0
  136. package/types/clr-angular-collapsible-panel.d.ts +73 -0
  137. package/types/clr-angular-data-datagrid.d.ts +1843 -0
  138. package/types/clr-angular-data-stack-view.d.ts +87 -0
  139. package/types/clr-angular-data-tree-view.d.ts +229 -0
  140. package/types/clr-angular-data.d.ts +15 -0
  141. package/types/clr-angular-emphasis-alert.d.ts +175 -0
  142. package/types/clr-angular-emphasis-badge.d.ts +25 -0
  143. package/types/clr-angular-emphasis-common.d.ts +6 -0
  144. package/types/clr-angular-emphasis-label.d.ts +29 -0
  145. package/types/clr-angular-emphasis.d.ts +15 -0
  146. package/types/clr-angular-forms-checkbox.d.ts +69 -0
  147. package/types/clr-angular-forms-combobox.d.ts +353 -0
  148. package/types/clr-angular-forms-common.d.ts +339 -0
  149. package/types/clr-angular-forms-datalist.d.ts +59 -0
  150. package/types/clr-angular-forms-datepicker.d.ts +986 -0
  151. package/types/clr-angular-forms-file-input.d.ts +193 -0
  152. package/types/clr-angular-forms-input.d.ts +29 -0
  153. package/types/clr-angular-forms-number-input.d.ts +43 -0
  154. package/types/clr-angular-forms-password.d.ts +52 -0
  155. package/types/clr-angular-forms-radio.d.ts +50 -0
  156. package/types/clr-angular-forms-range.d.ts +37 -0
  157. package/types/clr-angular-forms-select.d.ts +36 -0
  158. package/types/clr-angular-forms-textarea.d.ts +29 -0
  159. package/types/clr-angular-forms.d.ts +36 -0
  160. package/types/clr-angular-icon.d.ts +1498 -0
  161. package/types/clr-angular-layout-breadcrumbs.d.ts +45 -0
  162. package/types/clr-angular-layout-main-container.d.ts +28 -0
  163. package/types/clr-angular-layout-nav.d.ts +142 -0
  164. package/types/clr-angular-layout-tabs.d.ts +158 -0
  165. package/types/clr-angular-layout-vertical-nav.d.ts +128 -0
  166. package/types/clr-angular-layout.d.ts +19 -0
  167. package/types/clr-angular-modal.d.ts +160 -0
  168. package/types/clr-angular-popover-common.d.ts +254 -0
  169. package/types/clr-angular-popover-dropdown.d.ts +123 -0
  170. package/types/clr-angular-popover-signpost.d.ts +157 -0
  171. package/types/clr-angular-popover-tooltip.d.ts +83 -0
  172. package/types/clr-angular-popover.d.ts +16 -0
  173. package/types/clr-angular-progress-progress-bars.d.ts +57 -0
  174. package/types/clr-angular-progress-spinner.d.ts +44 -0
  175. package/types/clr-angular-stepper.d.ts +179 -0
  176. package/types/clr-angular-timeline.d.ts +86 -0
  177. package/types/clr-angular-utils-conditional.d.ts +132 -0
  178. package/types/clr-angular-utils-loading.d.ts +38 -0
  179. package/types/clr-angular-utils.d.ts +913 -0
  180. package/types/clr-angular-wizard.d.ts +1508 -0
  181. package/fesm2022/rossigee-clarity-angular.mjs.map +0 -1
  182. /package/types/{rossigee-clarity-angular.d.ts → clr-angular.d.ts} +0 -0
@@ -0,0 +1,3274 @@
1
+ import * as i5$1 from '@angular/common';
2
+ import { getLocaleDayNames, FormStyle, TranslationWidth, getLocaleMonthNames, getLocaleFirstDayOfWeek, getLocaleDateFormat, FormatWidth, isPlatformBrowser, CommonModule } from '@angular/common';
3
+ import * as i0 from '@angular/core';
4
+ import { Injectable, LOCALE_ID, Inject, DOCUMENT, PLATFORM_ID, HostListener, Component, EventEmitter, Input, Output, ViewChild, Optional, forwardRef, HostBinding, Self, Directive, NgModule } from '@angular/core';
5
+ import * as i7 from '@clr/angular/forms/common';
6
+ import { ClrAbstractContainer, ControlIdService, ControlClassService, FormsFocusService, NgControlService, WrappedFormControl, ClrCommonFormsModule } from '@clr/angular/forms/common';
7
+ import * as i4 from '@clr/angular/utils';
8
+ import { DATEPICKER_ENABLE_BREAKPOINT, Keys, isBooleanAttributeSet, CdkTrapFocusModule, ClrHostWrappingModule, ClrConditionalModule } from '@clr/angular/utils';
9
+ import { first, filter, startWith } from 'rxjs/operators';
10
+ import * as i1 from '@clr/angular/popover/common';
11
+ import { ClrPopoverPosition, ClrPopoverType, DROPDOWN_POSITIONS, ClrPopoverHostDirective, ClrPopoverModuleNext } from '@clr/angular/popover/common';
12
+ import { Subject, tap } from 'rxjs';
13
+ import * as i5 from '@clr/angular/icon';
14
+ import { ClarityIcons, successStandardIcon, errorStandardIcon, angleIcon, eventIcon, calendarIcon, ClrIcon } from '@clr/angular/icon';
15
+ import * as i6 from '@clr/angular/layout/vertical-nav';
16
+ import { ClrVerticalNavModule } from '@clr/angular/layout/vertical-nav';
17
+ import * as i1$1 from '@angular/forms';
18
+ import { NG_VALIDATORS } from '@angular/forms';
19
+
20
+ /*
21
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
22
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
23
+ * This software is released under MIT license.
24
+ * The full license information can be found in LICENSE in the root directory of this project.
25
+ */
26
+ class DateFormControlService {
27
+ constructor() {
28
+ this._touchedChange = new Subject();
29
+ this._dirtyChange = new Subject();
30
+ }
31
+ get touchedChange() {
32
+ return this._touchedChange.asObservable();
33
+ }
34
+ get dirtyChange() {
35
+ return this._dirtyChange.asObservable();
36
+ }
37
+ markAsTouched() {
38
+ this._touchedChange.next();
39
+ }
40
+ markAsDirty() {
41
+ this._dirtyChange.next();
42
+ }
43
+ // friendly wrapper
44
+ setDisabled(state) {
45
+ this.disabled = state;
46
+ }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateFormControlService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
48
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateFormControlService }); }
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateFormControlService, decorators: [{
51
+ type: Injectable
52
+ }] });
53
+
54
+ /*
55
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
56
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
57
+ * This software is released under MIT license.
58
+ * The full license information can be found in LICENSE in the root directory of this project.
59
+ */
60
+ class DayModel {
61
+ constructor(year, month, date) {
62
+ this.year = year;
63
+ this.month = month;
64
+ this.date = date;
65
+ }
66
+ /**
67
+ * Checks if the passed CalendarDate is equal to itself.
68
+ */
69
+ isEqual(day) {
70
+ if (day) {
71
+ return this.year === day.year && this.month === day.month && this.date === day.date;
72
+ }
73
+ return false;
74
+ }
75
+ toDate() {
76
+ return new Date(this.year, this.month, this.date);
77
+ }
78
+ /**
79
+ * Returns a new DayModel which is incremented based on the value passed.
80
+ */
81
+ incrementBy(value) {
82
+ // Creating new Javascript Date object to increment because
83
+ // it will automatically take care of switching to next or previous
84
+ // months & years without we having to worry about it.
85
+ const date = new Date(this.year, this.month, this.date + value);
86
+ return new DayModel(date.getFullYear(), date.getMonth(), date.getDate());
87
+ }
88
+ /**
89
+ * Clones the current day model.
90
+ */
91
+ clone() {
92
+ return new DayModel(this.year, this.month, this.date);
93
+ }
94
+ toComparisonString() {
95
+ return `${this.year}${this.pad(this.month)}${this.pad(this.date)}`;
96
+ }
97
+ toDateString() {
98
+ return this.toDate().toLocaleDateString(undefined, {
99
+ weekday: 'long',
100
+ month: 'long',
101
+ day: 'numeric',
102
+ year: 'numeric',
103
+ });
104
+ }
105
+ /**
106
+ * Compares the dates and returns boolean value based on the value passed
107
+ */
108
+ isBefore(day, dayInclusive = false) {
109
+ return dayInclusive
110
+ ? this.toDate().getTime() <= day?.toDate().getTime()
111
+ : this.toDate().getTime() < day?.toDate().getTime();
112
+ }
113
+ /**
114
+ * Compares the dates and returns boolean value based on the value passed
115
+ */
116
+ isAfter(day, dayInclusive = false) {
117
+ return dayInclusive
118
+ ? this.toDate().getTime() >= day?.toDate().getTime()
119
+ : this.toDate().getTime() > day?.toDate().getTime();
120
+ }
121
+ pad(num) {
122
+ return num < 10 ? `0${num}` : `${num}`;
123
+ }
124
+ }
125
+
126
+ /*
127
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
128
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
129
+ * This software is released under MIT license.
130
+ * The full license information can be found in LICENSE in the root directory of this project.
131
+ */
132
+ /**
133
+ * This is the en-001 short locale date format. Setting as default.
134
+ */
135
+ const DEFAULT_LOCALE_FORMAT = 'dd/MM/y';
136
+ // https://en.wikipedia.org/wiki/Date_format_by_country
137
+ const LITTLE_ENDIAN_REGEX = /d+.+m+.+y+/i;
138
+ const MIDDLE_ENDIAN_REGEX = /m+.+d+.+y+/i;
139
+ // No need for BIG_ENDIAN_REGEX because anything that doesn't satisfy the above 2
140
+ // is automatically BIG_ENDIAN
141
+ const DELIMITER_REGEX = /d+|m+|y+/i;
142
+ const USER_INPUT_REGEX = /\d+/g;
143
+ const MOBILE_USERAGENT_REGEX = /Mobi/i;
144
+ const RTL_REGEX = /\u200f/g;
145
+ const YEAR = 'YYYY';
146
+ const MONTH = 'MM';
147
+ const DATE = 'DD';
148
+ const LITTLE_ENDIAN = {
149
+ name: 'LITTLE_ENDIAN',
150
+ format: [DATE, MONTH, YEAR],
151
+ };
152
+ const MIDDLE_ENDIAN = {
153
+ name: 'MIDDLE_ENDIAN',
154
+ format: [MONTH, DATE, YEAR],
155
+ };
156
+ const BIG_ENDIAN = {
157
+ name: 'BIG_ENDIAN',
158
+ format: [YEAR, MONTH, DATE],
159
+ };
160
+ const NO_OF_DAYS_IN_A_WEEK = 7;
161
+ const NO_OF_ROWS_IN_CALENDAR_VIEW = 6;
162
+ const TOTAL_DAYS_IN_DAYS_VIEW = NO_OF_DAYS_IN_A_WEEK * NO_OF_ROWS_IN_CALENDAR_VIEW;
163
+
164
+ /*
165
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
166
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
167
+ * This software is released under MIT license.
168
+ * The full license information can be found in LICENSE in the root directory of this project.
169
+ */
170
+ /**
171
+ * Returns the number of days in a month.
172
+ */
173
+ function getNumberOfDaysInTheMonth(year, month) {
174
+ // If we go to the next month, but use a day of 0, it returns the last day from the previous month
175
+ return new Date(year, month + 1, 0).getDate();
176
+ }
177
+ /**
178
+ * Returns the day for the corresponding date where 0 represents Sunday.
179
+ */
180
+ function getDay(year, month, date) {
181
+ return new Date(year, month, date).getDay();
182
+ }
183
+ /**
184
+ * Takes in a year and if it is a 2 digit year, returns the corresponding 4 digit year.
185
+ * Window of 80 years before and 20 years after the present year.
186
+ * Credit: https://github.com/globalizejs/globalize/blob/e1b31cd6a4f1cff75b185b68b7a32220aac5196f/src/date/parse.js
187
+ */
188
+ function parseToFourDigitYear(year) {
189
+ if (year > 9999 || (year > 100 && year < 999) || year < 10) {
190
+ return -1;
191
+ }
192
+ if (year > 999) {
193
+ return year;
194
+ }
195
+ const currYear = new Date().getFullYear();
196
+ const century = Math.floor(currYear / 100) * 100;
197
+ let result = year + century;
198
+ if (result > currYear + 20) {
199
+ result = result - 100;
200
+ }
201
+ return result;
202
+ }
203
+ function datesAreEqual(date1, date2) {
204
+ if (date1 instanceof Date && date2 instanceof Date) {
205
+ return (date1.getFullYear() === date2.getFullYear() &&
206
+ date1.getMonth() === date2.getMonth() &&
207
+ date1.getDate() === date2.getDate());
208
+ }
209
+ else {
210
+ return false;
211
+ }
212
+ }
213
+
214
+ /*
215
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
216
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
217
+ * This software is released under MIT license.
218
+ * The full license information can be found in LICENSE in the root directory of this project.
219
+ */
220
+ /**
221
+ * Index of the day of the week, matching JavaScript's Date.getDay() convention.
222
+ * Used to override the locale-derived first day of the week in the date picker.
223
+ */
224
+ var ClrWeekday;
225
+ (function (ClrWeekday) {
226
+ ClrWeekday[ClrWeekday["Sunday"] = 0] = "Sunday";
227
+ ClrWeekday[ClrWeekday["Monday"] = 1] = "Monday";
228
+ ClrWeekday[ClrWeekday["Tuesday"] = 2] = "Tuesday";
229
+ ClrWeekday[ClrWeekday["Wednesday"] = 3] = "Wednesday";
230
+ ClrWeekday[ClrWeekday["Thursday"] = 4] = "Thursday";
231
+ ClrWeekday[ClrWeekday["Friday"] = 5] = "Friday";
232
+ ClrWeekday[ClrWeekday["Saturday"] = 6] = "Saturday";
233
+ })(ClrWeekday || (ClrWeekday = {}));
234
+
235
+ /*
236
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
237
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
238
+ * This software is released under MIT license.
239
+ * The full license information can be found in LICENSE in the root directory of this project.
240
+ */
241
+ /**
242
+ * This service extracts the Angular CLDR data needed by the datepicker.
243
+ */
244
+ class LocaleHelperService {
245
+ constructor(locale) {
246
+ this.locale = locale;
247
+ this._firstDayOfWeek = ClrWeekday.Sunday;
248
+ this.initializeLocaleData();
249
+ }
250
+ get firstDayOfWeek() {
251
+ return this._firstDayOfWeek;
252
+ }
253
+ get localeDays() {
254
+ return this._localeDays;
255
+ }
256
+ // leave for backward compatibility
257
+ get localeDaysNarrow() {
258
+ return this._localeDays.map(day => day.narrow);
259
+ }
260
+ get localeMonthsAbbreviated() {
261
+ return this._localeMonthsAbbreviated;
262
+ }
263
+ get localeMonthsWide() {
264
+ return this._localeMonthsWide;
265
+ }
266
+ get localeDateFormat() {
267
+ return this._localeDateFormat;
268
+ }
269
+ /**
270
+ * Overrides the first day of the week regardless of locale.
271
+ * Accepts a `ClrWeekday` value (Sunday=0 through Saturday=6), or null to revert to locale default.
272
+ * Incorrect values will revert to default value (Sunday).
273
+ */
274
+ updateFirstDayOfWeek(day) {
275
+ if (day === null || day < ClrWeekday.Sunday || day > ClrWeekday.Saturday) {
276
+ this.initializeLocaleFirstDayOfWeek();
277
+ this.initializeLocaleDays();
278
+ return;
279
+ }
280
+ this._firstDayOfWeek = day;
281
+ this.initializeLocaleDays();
282
+ }
283
+ /**
284
+ * Initializes the locale data.
285
+ */
286
+ initializeLocaleData() {
287
+ // Order in which these functions is called is very important.
288
+ this.initializeLocaleFirstDayOfWeek();
289
+ this.initializeLocaleDateFormat();
290
+ this.initializeLocaleMonthsAbbreviated();
291
+ this.initializeLocaleMonthsWide();
292
+ this.initializeLocaleDays();
293
+ }
294
+ /**
295
+ * Initialize day names based on the locale.
296
+ * eg: [{day: Sunday, narrow: S}, {day: Monday, narrow: M}...] for en-US.
297
+ */
298
+ initializeLocaleDays() {
299
+ // Get locale day names starting with Sunday
300
+ const tempArr = [];
301
+ const tempWideArr = getLocaleDayNames(this.locale, FormStyle.Standalone, TranslationWidth.Wide).slice();
302
+ const tempNarrowArr = getLocaleDayNames(this.locale, FormStyle.Standalone, TranslationWidth.Narrow).slice();
303
+ for (let i = 0; i < 7; i++) {
304
+ tempArr.push({ day: tempWideArr[i], narrow: tempNarrowArr[i] });
305
+ }
306
+ // Rearrange the tempArr to start with the first day of the week based on the locale (default or override).
307
+ if (this.firstDayOfWeek > ClrWeekday.Sunday) {
308
+ const prevDays = tempArr.splice(0, this.firstDayOfWeek);
309
+ tempArr.push(...prevDays);
310
+ }
311
+ this._localeDays = tempArr;
312
+ }
313
+ /**
314
+ * Initializes the array of month names in the TranslationWidth.Abbreviated format.
315
+ * e.g. `[Jan, Feb, ...]` for en-US
316
+ */
317
+ initializeLocaleMonthsAbbreviated() {
318
+ this._localeMonthsAbbreviated = getLocaleMonthNames(this.locale, FormStyle.Standalone, TranslationWidth.Abbreviated).slice();
319
+ }
320
+ /**
321
+ * Initializes the array of month names in the TranslationWidth.Wide format.
322
+ * e.g. `[January, February, ...]` for en-US
323
+ */
324
+ initializeLocaleMonthsWide() {
325
+ this._localeMonthsWide = getLocaleMonthNames(this.locale, FormStyle.Standalone, TranslationWidth.Wide).slice();
326
+ }
327
+ /**
328
+ * Initializes the first day of the week based on the locale.
329
+ */
330
+ initializeLocaleFirstDayOfWeek() {
331
+ this._firstDayOfWeek = getLocaleFirstDayOfWeek(this.locale);
332
+ }
333
+ initializeLocaleDateFormat() {
334
+ this._localeDateFormat = getLocaleDateFormat(this.locale, FormatWidth.Short);
335
+ }
336
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LocaleHelperService, deps: [{ token: LOCALE_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
337
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LocaleHelperService }); }
338
+ }
339
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: LocaleHelperService, decorators: [{
340
+ type: Injectable
341
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
342
+ type: Inject,
343
+ args: [LOCALE_ID]
344
+ }] }] });
345
+
346
+ /*
347
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
348
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
349
+ * This software is released under MIT license.
350
+ * The full license information can be found in LICENSE in the root directory of this project.
351
+ */
352
+ class DateIOService {
353
+ constructor(localeHelperService) {
354
+ /**
355
+ * This is the default range. It approximates the beginning of time to the end of time.
356
+ * The disabled dates are the dates that are not allowed to be selected.
357
+ * The min date is the earliest date that can be selected.
358
+ * The max date is the latest date that can be selected.
359
+ * Unless a minDate or maxDate is set with the native HTML5 api the range is all dates
360
+ */
361
+ this.disabledDates = {
362
+ minDate: new DayModel(0, 0, 1),
363
+ maxDate: new DayModel(9999, 11, 31),
364
+ };
365
+ this.cldrLocaleDateFormat = DEFAULT_LOCALE_FORMAT;
366
+ this.minDateChange = new Subject();
367
+ this.maxDateChange = new Subject();
368
+ this.localeDisplayFormat = LITTLE_ENDIAN;
369
+ this.delimiters = ['/', '/'];
370
+ this.cldrLocaleDateFormat = localeHelperService.localeDateFormat;
371
+ this.initializeLocaleDisplayFormat();
372
+ }
373
+ get placeholderText() {
374
+ const format = this.localeDisplayFormat.format;
375
+ return format[0] + this.delimiters[0] + format[1] + this.delimiters[1] + format[2];
376
+ }
377
+ setMinDate(date) {
378
+ // NOTE: I'm expecting consumers to pass one of four things here:
379
+ // A proper date string(2019-11-11), null, undefined or empty string ('')
380
+ if (!date) {
381
+ // attribute binding was removed, reset back to the beginning of time
382
+ this.disabledDates.minDate = new DayModel(0, 0, 1);
383
+ }
384
+ else {
385
+ const [year, month, day] = date.split('-').map(n => parseInt(n, 10));
386
+ this.disabledDates.minDate = new DayModel(year, month - 1, day);
387
+ }
388
+ this.minDateChange.next(this.disabledDates.minDate);
389
+ }
390
+ setMaxDate(date) {
391
+ // NOTE: I'm expecting consumers to pass one of four things here:
392
+ // A proper date string(2019-11-11), null, undefined or empty string ('')
393
+ if (!date) {
394
+ // attribute binding was removed, reset forward to the end of time
395
+ this.disabledDates.maxDate = new DayModel(9999, 11, 31);
396
+ }
397
+ else {
398
+ const [year, month, day] = date.split('-').map(n => parseInt(n, 10));
399
+ this.disabledDates.maxDate = new DayModel(year, month - 1, day);
400
+ }
401
+ this.maxDateChange.next(this.disabledDates.maxDate);
402
+ }
403
+ setRangeOptions(rangeOptions) {
404
+ const validatedRangeOption = this.validateDateRangeOptions(rangeOptions);
405
+ this.dateRangeOptions = validatedRangeOption || [];
406
+ }
407
+ getRangeOptions() {
408
+ return this.dateRangeOptions;
409
+ }
410
+ toLocaleDisplayFormatString(date) {
411
+ if (date) {
412
+ if (isNaN(date.getTime())) {
413
+ return '';
414
+ }
415
+ const dateNo = date.getDate();
416
+ const monthNo = date.getMonth() + 1;
417
+ const dateStr = dateNo > 9 ? dateNo.toString() : '0' + dateNo;
418
+ const monthStr = monthNo > 9 ? monthNo.toString() : '0' + monthNo;
419
+ if (this.localeDisplayFormat === LITTLE_ENDIAN) {
420
+ return dateStr + this.delimiters[0] + monthStr + this.delimiters[1] + date.getFullYear();
421
+ }
422
+ else if (this.localeDisplayFormat === MIDDLE_ENDIAN) {
423
+ return monthStr + this.delimiters[0] + dateStr + this.delimiters[1] + date.getFullYear();
424
+ }
425
+ else {
426
+ return date.getFullYear() + this.delimiters[0] + monthStr + this.delimiters[1] + dateStr;
427
+ }
428
+ }
429
+ return '';
430
+ }
431
+ getDateValueFromDateString(date) {
432
+ if (!date || typeof date !== 'string') {
433
+ return null;
434
+ }
435
+ const dateParts = date.match(USER_INPUT_REGEX);
436
+ if (!dateParts || dateParts.length !== 3) {
437
+ return null;
438
+ }
439
+ const [firstPart, secondPart, thirdPart] = dateParts;
440
+ if (this.localeDisplayFormat === LITTLE_ENDIAN) {
441
+ // secondPart is month && firstPart is date
442
+ return this.validateAndGetDate(thirdPart, secondPart, firstPart);
443
+ }
444
+ else if (this.localeDisplayFormat === MIDDLE_ENDIAN) {
445
+ // firstPart is month && secondPart is date
446
+ return this.validateAndGetDate(thirdPart, firstPart, secondPart);
447
+ }
448
+ else {
449
+ // secondPart is month && thirdPart is date
450
+ return this.validateAndGetDate(firstPart, secondPart, thirdPart);
451
+ }
452
+ }
453
+ validateDateRangeOptions(rangeOptions) {
454
+ const validOptions = [];
455
+ rangeOptions?.forEach((rangeOption) => {
456
+ if (rangeOption?.value?.length !== 2 ||
457
+ Object.prototype.toString.call(rangeOption?.value[0]) !== '[object Date]' ||
458
+ Object.prototype.toString.call(rangeOption?.value[1]) !== '[object Date]') {
459
+ return;
460
+ }
461
+ validOptions.push(rangeOption);
462
+ });
463
+ return validOptions;
464
+ }
465
+ initializeLocaleDisplayFormat() {
466
+ const format = this.cldrLocaleDateFormat.toLocaleLowerCase();
467
+ if (LITTLE_ENDIAN_REGEX.test(format)) {
468
+ this.localeDisplayFormat = LITTLE_ENDIAN;
469
+ }
470
+ else if (MIDDLE_ENDIAN_REGEX.test(format)) {
471
+ this.localeDisplayFormat = MIDDLE_ENDIAN;
472
+ }
473
+ else {
474
+ // everything else is set to BIG-ENDIAN FORMAT
475
+ this.localeDisplayFormat = BIG_ENDIAN;
476
+ }
477
+ this.extractDelimiters();
478
+ }
479
+ extractDelimiters() {
480
+ if (this.cldrLocaleDateFormat) {
481
+ // Sanitize Date Format. Remove RTL characters.
482
+ // FIXME: When we support RTL, remove this and handle it correctly.
483
+ const localeFormat = this.cldrLocaleDateFormat.replace(RTL_REGEX, '');
484
+ const delimiters = localeFormat.split(DELIMITER_REGEX);
485
+ // NOTE: The split from the CLDR date format should always result
486
+ // in an arary with 4 elements. The 1st and the 2nd values are the delimiters
487
+ // we will use in order.
488
+ // Eg: "dd/MM/y".split(/d+|m+|y+/i) results in ["", "/", "/", ""]
489
+ if (delimiters && delimiters.length === 4) {
490
+ this.delimiters = [delimiters[1], delimiters[2]];
491
+ }
492
+ else {
493
+ console.error('Unexpected date format received. Delimiters extracted: ', delimiters);
494
+ }
495
+ }
496
+ }
497
+ /**
498
+ * Checks if the month entered by the user is valid or not.
499
+ * Note: Month is 0 based.
500
+ */
501
+ isValidMonth(month) {
502
+ return month > -1 && month < 12;
503
+ }
504
+ /**
505
+ * Checks if the date is valid depending on the year and month provided.
506
+ */
507
+ isValidDate(year, month, date) {
508
+ return date > 0 && date <= getNumberOfDaysInTheMonth(year, month);
509
+ }
510
+ /**
511
+ * Validates the parameters provided and returns the date.
512
+ * If the parameters are not
513
+ * valid then return null.
514
+ * NOTE: (Month here is 1 based since the user has provided that as an input)
515
+ */
516
+ validateAndGetDate(year, month, date) {
517
+ // I don't know whats wrong with the TS compiler. It throws an error if I write
518
+ // the below if statement. The error is:
519
+ // Operator '!==' cannot be applied to types '2' and '4'
520
+ // More info here: https://github.com/Microsoft/TypeScript/issues/12794#issuecomment-270342936
521
+ /*
522
+ if (year.length !== 2 || year.length !== 4) {
523
+ return null;
524
+ }
525
+ */
526
+ // Instead I have to write the logic like this x-(
527
+ const y = +year;
528
+ const m = +month - 1; // month is 0 based
529
+ const d = +date;
530
+ if (!this.isValidMonth(m) || !this.isValidDate(y, m, d)) {
531
+ return null;
532
+ }
533
+ const result = parseToFourDigitYear(y);
534
+ return result !== -1 ? new Date(result, m, d) : null;
535
+ }
536
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateIOService, deps: [{ token: LocaleHelperService }], target: i0.ɵɵFactoryTarget.Injectable }); }
537
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateIOService }); }
538
+ }
539
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateIOService, decorators: [{
540
+ type: Injectable
541
+ }], ctorParameters: () => [{ type: LocaleHelperService }] });
542
+
543
+ /*
544
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
545
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
546
+ * This software is released under MIT license.
547
+ * The full license information can be found in LICENSE in the root directory of this project.
548
+ */
549
+ class CalendarModel {
550
+ constructor(year, month) {
551
+ this.year = year;
552
+ this.month = month;
553
+ this.initializeDaysInCalendar();
554
+ }
555
+ /**
556
+ * Checks if the calendar passed is equal to the current calendar.
557
+ */
558
+ isEqual(calendar) {
559
+ if (calendar) {
560
+ return this.year === calendar.year && this.month === calendar.month;
561
+ }
562
+ return false;
563
+ }
564
+ /**
565
+ * Checks if a DayModel is in the Calendar
566
+ */
567
+ isDayInCalendar(day) {
568
+ if (day) {
569
+ return this.year === day.year && this.month === day.month;
570
+ }
571
+ return false;
572
+ }
573
+ /**
574
+ * Returns CalendarModel of the previous month.
575
+ */
576
+ previousMonth() {
577
+ if (this.month === 0) {
578
+ return new CalendarModel(this.year - 1, 11);
579
+ }
580
+ else {
581
+ return new CalendarModel(this.year, this.month - 1);
582
+ }
583
+ }
584
+ /**
585
+ * Returns CalendarModel of the next month.
586
+ */
587
+ nextMonth() {
588
+ if (this.month === 11) {
589
+ return new CalendarModel(this.year + 1, 0);
590
+ }
591
+ else {
592
+ return new CalendarModel(this.year, this.month + 1);
593
+ }
594
+ }
595
+ /**
596
+ * Returns CalendarModel of the previous year.
597
+ */
598
+ previousYear() {
599
+ return new CalendarModel(this.year - 1, this.month);
600
+ }
601
+ /**
602
+ * Returns CalendarModel of the next year.
603
+ */
604
+ nextYear() {
605
+ return new CalendarModel(this.year + 1, this.month);
606
+ }
607
+ /**
608
+ * Populates the days array with the DayModels in the current Calendar.
609
+ */
610
+ initializeDaysInCalendar() {
611
+ const noOfDaysInCalendar = getNumberOfDaysInTheMonth(this.year, this.month);
612
+ this.days = Array(noOfDaysInCalendar)
613
+ .fill(null)
614
+ .map((_date, index) => {
615
+ return new DayModel(this.year, this.month, index + 1);
616
+ });
617
+ }
618
+ }
619
+
620
+ /*
621
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
622
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
623
+ * This software is released under MIT license.
624
+ * The full license information can be found in LICENSE in the root directory of this project.
625
+ */
626
+ /**
627
+ * This service is responsible for:
628
+ * 1. Initializing the displayed calendar.
629
+ * 2. Moving the calendar to the next, previous or current months
630
+ * 3. Managing the focused and selected day models.
631
+ */
632
+ class DateNavigationService {
633
+ constructor() {
634
+ this.isRangePicker = false;
635
+ this.hasActionButtons = false;
636
+ this._todaysFullDate = new Date();
637
+ this._selectedDayChange = new Subject();
638
+ this._selectedEndDayChange = new Subject();
639
+ this._displayedCalendarChange = new Subject();
640
+ this._focusOnCalendarChange = new Subject();
641
+ this._refreshCalendarView = new Subject();
642
+ this._focusedDayChange = new Subject();
643
+ }
644
+ get today() {
645
+ return this._today;
646
+ }
647
+ get displayedCalendar() {
648
+ return this._displayedCalendar;
649
+ }
650
+ get selectedDayChange() {
651
+ return this._selectedDayChange.asObservable();
652
+ }
653
+ get selectedEndDayChange() {
654
+ return this._selectedEndDayChange.asObservable();
655
+ }
656
+ /**
657
+ * This observable lets the subscriber know that the displayed calendar has changed.
658
+ */
659
+ get displayedCalendarChange() {
660
+ return this._displayedCalendarChange.asObservable();
661
+ }
662
+ /**
663
+ * This observable lets the subscriber know that the focus should be applied on the calendar.
664
+ */
665
+ get focusOnCalendarChange() {
666
+ return this._focusOnCalendarChange.asObservable();
667
+ }
668
+ /**
669
+ * This observable lets the subscriber know that the focused day in the displayed calendar has changed.
670
+ */
671
+ get focusedDayChange() {
672
+ return this._focusedDayChange.asObservable().pipe(tap((day) => (this.focusedDay = day)));
673
+ }
674
+ /**
675
+ * This observable lets the subscriber know that the displayed calendar has changed.
676
+ */
677
+ get refreshCalendarView() {
678
+ return this._refreshCalendarView.asObservable();
679
+ }
680
+ /**
681
+ * Notifies that the selected day has changed so that the date can be emitted to the user.
682
+ */
683
+ notifySelectedDayChanged(dayObject, { emitEvent } = { emitEvent: true }) {
684
+ if (this.isRangePicker) {
685
+ const { startDate, endDate } = dayObject;
686
+ if (startDate && endDate) {
687
+ this.setSelectedDay(startDate, emitEvent);
688
+ this.setSelectedEndDay(endDate, emitEvent);
689
+ }
690
+ else {
691
+ if (endDate !== null) {
692
+ this.setSelectedEndDay(endDate, emitEvent);
693
+ }
694
+ if (startDate !== null) {
695
+ this.setSelectedDay(startDate, emitEvent);
696
+ }
697
+ }
698
+ }
699
+ else {
700
+ const day = dayObject;
701
+ this.setSelectedDay(day, emitEvent);
702
+ }
703
+ this._refreshCalendarView.next();
704
+ }
705
+ /**
706
+ * Initializes the calendar based on the selected day.
707
+ */
708
+ initializeCalendar() {
709
+ this.focusedDay = null; // Can be removed later on the store focus
710
+ this.initializeTodaysDate();
711
+ if (this.selectedDay) {
712
+ this._displayedCalendar = new CalendarModel(this.selectedDay.year, this.selectedDay.month);
713
+ }
714
+ else {
715
+ this._displayedCalendar = new CalendarModel(this.today.year, this.today.month);
716
+ }
717
+ }
718
+ changeMonth(month) {
719
+ this.setDisplayedCalendar(new CalendarModel(this._displayedCalendar.year, month));
720
+ }
721
+ changeYear(year) {
722
+ this.setDisplayedCalendar(new CalendarModel(year, this._displayedCalendar.month));
723
+ }
724
+ /**
725
+ * Moves the displayed calendar to the next month.
726
+ */
727
+ moveToNextMonth() {
728
+ this.setDisplayedCalendar(this._displayedCalendar.nextMonth());
729
+ }
730
+ /**
731
+ * Moves the displayed calendar to the previous month.
732
+ */
733
+ moveToPreviousMonth() {
734
+ this.setDisplayedCalendar(this._displayedCalendar.previousMonth());
735
+ }
736
+ /**
737
+ * Moves the displayed calendar to the next year.
738
+ */
739
+ moveToNextYear() {
740
+ this.setDisplayedCalendar(this._displayedCalendar.nextYear());
741
+ }
742
+ /**
743
+ * Moves the displayed calendar to the previous year.
744
+ */
745
+ moveToPreviousYear() {
746
+ this.setDisplayedCalendar(this._displayedCalendar.previousYear());
747
+ }
748
+ /**
749
+ * Moves the displayed calendar to the current month and year.
750
+ */
751
+ moveToCurrentMonth() {
752
+ if (!this.displayedCalendar.isDayInCalendar(this.today)) {
753
+ this.setDisplayedCalendar(new CalendarModel(this.today.year, this.today.month));
754
+ }
755
+ this._focusOnCalendarChange.next();
756
+ }
757
+ moveToSpecificMonth(day) {
758
+ if (!this.displayedCalendar.isDayInCalendar(day)) {
759
+ this.setDisplayedCalendar(new CalendarModel(day.year, day.month));
760
+ }
761
+ }
762
+ incrementFocusDay(value) {
763
+ this.hoveredDay = this.focusedDay = this.focusedDay.incrementBy(value);
764
+ if (this._displayedCalendar.isDayInCalendar(this.focusedDay)) {
765
+ this._focusedDayChange.next(this.focusedDay);
766
+ }
767
+ else {
768
+ this.setDisplayedCalendar(new CalendarModel(this.focusedDay.year, this.focusedDay.month));
769
+ }
770
+ this._focusOnCalendarChange.next();
771
+ }
772
+ resetSelectedDay() {
773
+ this.selectedDay = this.persistedDate;
774
+ this.selectedEndDay = this.persistedEndDate;
775
+ }
776
+ convertDateToDayModel(date) {
777
+ return new DayModel(date.getFullYear(), date.getMonth(), date.getDate());
778
+ }
779
+ setSelectedDay(dayModel, emitEvent) {
780
+ this.selectedDay = dayModel;
781
+ if (emitEvent) {
782
+ this._selectedDayChange.next(dayModel);
783
+ }
784
+ }
785
+ setSelectedEndDay(dayModel, emitEvent) {
786
+ this.selectedEndDay = dayModel;
787
+ if (emitEvent) {
788
+ this._selectedEndDayChange.next(dayModel);
789
+ }
790
+ }
791
+ // not a setter because i want this to remain private
792
+ setDisplayedCalendar(value) {
793
+ if (!this._displayedCalendar.isEqual(value)) {
794
+ this._displayedCalendar = value;
795
+ this._displayedCalendarChange.next();
796
+ }
797
+ }
798
+ initializeTodaysDate() {
799
+ this._todaysFullDate = new Date();
800
+ this._today = new DayModel(this._todaysFullDate.getFullYear(), this._todaysFullDate.getMonth(), this._todaysFullDate.getDate());
801
+ }
802
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateNavigationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
803
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateNavigationService }); }
804
+ }
805
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DateNavigationService, decorators: [{
806
+ type: Injectable
807
+ }] });
808
+
809
+ /*
810
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
811
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
812
+ * This software is released under MIT license.
813
+ * The full license information can be found in LICENSE in the root directory of this project.
814
+ */
815
+ class DatepickerEnabledService {
816
+ constructor(_document) {
817
+ this._document = _document;
818
+ this._isUserAgentMobile = false;
819
+ if (_document) {
820
+ this._isUserAgentMobile = MOBILE_USERAGENT_REGEX.test(_document.defaultView.navigator.userAgent);
821
+ this._innerWidth = _document.defaultView.innerWidth;
822
+ }
823
+ }
824
+ /**
825
+ * Returns if the calendar should be active or not.
826
+ * If the user agent is mobile and the screen width is less than DATEPICKER_ACTIVE_BREAKPOINT
827
+ * then the calendar is inactive.
828
+ */
829
+ get isEnabled() {
830
+ // https://developer.mozilla.org/en-US/docs/Web/HTTP/Browser_detection_using_the_user_agent
831
+ // What they recommend is:
832
+ //"In summary, we recommend looking for the string 'Mobi'
833
+ // anywhere in the User Agent to detect a mobile device."
834
+ if (this._document) {
835
+ if (this._innerWidth < DATEPICKER_ENABLE_BREAKPOINT && this._isUserAgentMobile) {
836
+ return false;
837
+ }
838
+ }
839
+ return true;
840
+ }
841
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerEnabledService, deps: [{ token: DOCUMENT }], target: i0.ɵɵFactoryTarget.Injectable }); }
842
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerEnabledService }); }
843
+ }
844
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerEnabledService, decorators: [{
845
+ type: Injectable
846
+ }], ctorParameters: () => [{ type: undefined, decorators: [{
847
+ type: Inject,
848
+ args: [DOCUMENT]
849
+ }] }] });
850
+
851
+ /*
852
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
853
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
854
+ * This software is released under MIT license.
855
+ * The full license information can be found in LICENSE in the root directory of this project.
856
+ */
857
+ /**
858
+ * This service manages which view is visible in the datepicker popover.
859
+ */
860
+ class ViewManagerService {
861
+ constructor() {
862
+ this.position = ClrPopoverPosition.BOTTOM_LEFT;
863
+ this._currentView = "DAYVIEW" /* DatepickerViewEnum.DAYVIEW */;
864
+ }
865
+ get isDayView() {
866
+ return this._currentView === "DAYVIEW" /* DatepickerViewEnum.DAYVIEW */;
867
+ }
868
+ get isYearView() {
869
+ return this._currentView === "YEARVIEW" /* DatepickerViewEnum.YEARVIEW */;
870
+ }
871
+ get isMonthView() {
872
+ return this._currentView === "MONTHVIEW" /* DatepickerViewEnum.MONTHVIEW */;
873
+ }
874
+ changeToMonthView() {
875
+ this._currentView = "MONTHVIEW" /* DatepickerViewEnum.MONTHVIEW */;
876
+ }
877
+ changeToYearView() {
878
+ this._currentView = "YEARVIEW" /* DatepickerViewEnum.YEARVIEW */;
879
+ }
880
+ changeToDayView() {
881
+ this._currentView = "DAYVIEW" /* DatepickerViewEnum.DAYVIEW */;
882
+ }
883
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ViewManagerService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
884
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ViewManagerService }); }
885
+ }
886
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ViewManagerService, decorators: [{
887
+ type: Injectable
888
+ }] });
889
+
890
+ /*
891
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
892
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
893
+ * This software is released under MIT license.
894
+ * The full license information can be found in LICENSE in the root directory of this project.
895
+ */
896
+ /**
897
+ * This service focuses the day that is focusable in the calendar.
898
+ */
899
+ class DatepickerFocusService {
900
+ constructor(_ngZone, platformId) {
901
+ this._ngZone = _ngZone;
902
+ this.platformId = platformId;
903
+ }
904
+ focusCell(elRef) {
905
+ this._ngZone.runOutsideAngular(() => {
906
+ this.ngZoneIsStableInBrowser().subscribe(() => {
907
+ const focusEl = elRef.nativeElement.querySelector('[tabindex="0"]');
908
+ if (focusEl) {
909
+ focusEl.focus();
910
+ }
911
+ });
912
+ });
913
+ }
914
+ focusInput(element) {
915
+ this._ngZone.runOutsideAngular(() => this.ngZoneIsStableInBrowser().subscribe(() => element.focus()));
916
+ }
917
+ elementIsFocused(element) {
918
+ return isPlatformBrowser(this.platformId) && document.activeElement === element;
919
+ }
920
+ ngZoneIsStableInBrowser() {
921
+ // Credit: Material: https://github.com/angular/material2/blob/master/src/lib/datepicker/calendar.ts
922
+ return this._ngZone.onStable.asObservable().pipe(first(), filter(() => isPlatformBrowser(this.platformId)));
923
+ }
924
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerFocusService, deps: [{ token: i0.NgZone }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable }); }
925
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerFocusService }); }
926
+ }
927
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: DatepickerFocusService, decorators: [{
928
+ type: Injectable
929
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: undefined, decorators: [{
930
+ type: Inject,
931
+ args: [PLATFORM_ID]
932
+ }] }] });
933
+
934
+ /*
935
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
936
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
937
+ * This software is released under MIT license.
938
+ * The full license information can be found in LICENSE in the root directory of this project.
939
+ */
940
+ class ClrMonthpicker {
941
+ constructor(_localeHelperService, _dateNavigationService, _datepickerFocusService, _elRef, _viewManagerService, commonStrings) {
942
+ this._localeHelperService = _localeHelperService;
943
+ this._dateNavigationService = _dateNavigationService;
944
+ this._datepickerFocusService = _datepickerFocusService;
945
+ this._elRef = _elRef;
946
+ this._viewManagerService = _viewManagerService;
947
+ this.commonStrings = commonStrings;
948
+ this._focusedMonthIndex = this.calendarMonthIndex;
949
+ }
950
+ /**
951
+ * Gets the months array which is used to rendered the monthpicker view.
952
+ * Months are in the TranslationWidth.Wide format.
953
+ */
954
+ get monthNames() {
955
+ return this._localeHelperService.localeMonthsWide;
956
+ }
957
+ /**
958
+ * Gets the month value of the Calendar.
959
+ */
960
+ get calendarMonthIndex() {
961
+ return this._dateNavigationService.displayedCalendar.month;
962
+ }
963
+ /**
964
+ * Gets the year which the user is currently on.
965
+ */
966
+ get calendarEndMonthIndex() {
967
+ return this._dateNavigationService.selectedEndDay?.month;
968
+ }
969
+ get yearAttrString() {
970
+ return this.commonStrings.parse(this.commonStrings.keys.datepickerSelectYearText, {
971
+ CALENDAR_YEAR: this.calendarYear.toString(),
972
+ });
973
+ }
974
+ /**
975
+ * Returns the year value of the calendar.
976
+ */
977
+ get calendarYear() {
978
+ return this._dateNavigationService.displayedCalendar.year;
979
+ }
980
+ get currentCalendarYear() {
981
+ return new Date().getFullYear();
982
+ }
983
+ get currentCalendarMonth() {
984
+ return new Date().getMonth();
985
+ }
986
+ getIsRangeStartMonth(monthIndex) {
987
+ return (this._dateNavigationService.isRangePicker &&
988
+ this.calendarYear === this._dateNavigationService.selectedDay?.year &&
989
+ monthIndex === this._dateNavigationService.selectedDay?.month);
990
+ }
991
+ getIsRangeEndMonth(monthIndex) {
992
+ return (this._dateNavigationService.isRangePicker &&
993
+ this.calendarYear === this._dateNavigationService.selectedEndDay?.year &&
994
+ monthIndex === this._dateNavigationService.selectedEndDay?.month);
995
+ }
996
+ /**
997
+ * Calls the ViewManagerService to change to the yearpicker view.
998
+ */
999
+ changeToYearView() {
1000
+ this._viewManagerService.changeToYearView();
1001
+ }
1002
+ /**
1003
+ * Focuses on the current calendar month when the View is initialized.
1004
+ */
1005
+ ngAfterViewInit() {
1006
+ this._datepickerFocusService.focusCell(this._elRef);
1007
+ }
1008
+ /**
1009
+ * Handles the Keyboard arrow navigation for the monthpicker.
1010
+ */
1011
+ onKeyDown(event) {
1012
+ // NOTE: Didn't move this to the date navigation service because
1013
+ // the logic is fairly simple and it didn't make sense for me
1014
+ // to create extra observables just to move this logic to the service.
1015
+ if (event) {
1016
+ const key = event.key;
1017
+ if (key === Keys.ArrowUp && this._focusedMonthIndex > 1) {
1018
+ event.preventDefault();
1019
+ this._focusedMonthIndex -= 2;
1020
+ this._datepickerFocusService.focusCell(this._elRef);
1021
+ }
1022
+ else if (key === Keys.ArrowDown && this._focusedMonthIndex < 10) {
1023
+ event.preventDefault();
1024
+ this._focusedMonthIndex += 2;
1025
+ this._datepickerFocusService.focusCell(this._elRef);
1026
+ }
1027
+ else if (key === Keys.ArrowRight && this._focusedMonthIndex < 11) {
1028
+ event.preventDefault();
1029
+ this._focusedMonthIndex++;
1030
+ this._datepickerFocusService.focusCell(this._elRef);
1031
+ }
1032
+ else if (key === Keys.ArrowLeft && this._focusedMonthIndex > 0) {
1033
+ event.preventDefault();
1034
+ this._focusedMonthIndex--;
1035
+ this._datepickerFocusService.focusCell(this._elRef);
1036
+ }
1037
+ }
1038
+ }
1039
+ isSelected(monthIndex) {
1040
+ return ((this._dateNavigationService.selectedDay?.year === this.calendarYear &&
1041
+ monthIndex === this._dateNavigationService.selectedDay?.month) ||
1042
+ (this._dateNavigationService.selectedEndDay?.year === this.calendarYear &&
1043
+ monthIndex === this.calendarEndMonthIndex));
1044
+ }
1045
+ /**
1046
+ * Calls the DateNavigationService to update the hovered month value of the calendar
1047
+ */
1048
+ onHover(monthIndex) {
1049
+ this._dateNavigationService.hoveredMonth = monthIndex;
1050
+ }
1051
+ /**
1052
+ * Calls the DateNavigationService to update the month value of the calendar.
1053
+ * Also changes the view to the daypicker.
1054
+ */
1055
+ changeMonth(monthIndex) {
1056
+ this._dateNavigationService.changeMonth(monthIndex);
1057
+ this._viewManagerService.changeToDayView();
1058
+ }
1059
+ /**
1060
+ * Compares the month passed to the focused month and returns the tab index.
1061
+ */
1062
+ getTabIndex(monthIndex) {
1063
+ return monthIndex === this._focusedMonthIndex ? 0 : -1;
1064
+ }
1065
+ /**
1066
+ * Calls the DateNavigationService to move to the next month.
1067
+ */
1068
+ nextYear() {
1069
+ this._dateNavigationService.moveToNextYear();
1070
+ }
1071
+ /**
1072
+ * Calls the DateNavigationService to move to the previous month.
1073
+ */
1074
+ previousYear() {
1075
+ this._dateNavigationService.moveToPreviousYear();
1076
+ }
1077
+ /**
1078
+ * Calls the DateNavigationService to move to the current month.
1079
+ */
1080
+ currentYear() {
1081
+ this._dateNavigationService.moveToCurrentMonth();
1082
+ }
1083
+ /**
1084
+ * Applicable only to date range picker
1085
+ * Compares the month passed is in between the start and end date range
1086
+ */
1087
+ isInRange(monthIndex) {
1088
+ if (!this._dateNavigationService.isRangePicker) {
1089
+ return false;
1090
+ }
1091
+ if (this._dateNavigationService.selectedDay && this._dateNavigationService.selectedEndDay) {
1092
+ return ((this.calendarYear === this._dateNavigationService.selectedDay.year &&
1093
+ monthIndex > this._dateNavigationService.selectedDay.month &&
1094
+ this.calendarYear === this._dateNavigationService.selectedEndDay.year &&
1095
+ monthIndex < this._dateNavigationService.selectedEndDay.month) ||
1096
+ (this._dateNavigationService.selectedDay.year !== this._dateNavigationService.selectedEndDay.year &&
1097
+ this.calendarYear === this._dateNavigationService.selectedDay.year &&
1098
+ monthIndex > this._dateNavigationService.selectedDay.month) ||
1099
+ (this._dateNavigationService.selectedDay.year !== this._dateNavigationService.selectedEndDay.year &&
1100
+ this.calendarYear === this._dateNavigationService.selectedEndDay.year &&
1101
+ monthIndex < this._dateNavigationService.selectedEndDay.month) ||
1102
+ (this.calendarYear > this._dateNavigationService.selectedDay.year &&
1103
+ this.calendarYear < this._dateNavigationService.selectedEndDay.year));
1104
+ }
1105
+ else if (this._dateNavigationService.selectedDay && !this._dateNavigationService.selectedEndDay) {
1106
+ return ((this.calendarYear === this._dateNavigationService.selectedDay.year &&
1107
+ monthIndex > this._dateNavigationService.selectedDay.month &&
1108
+ monthIndex < this._dateNavigationService.hoveredMonth) ||
1109
+ (this.calendarYear > this._dateNavigationService.selectedDay.year &&
1110
+ monthIndex < this._dateNavigationService.hoveredMonth));
1111
+ }
1112
+ else {
1113
+ return false;
1114
+ }
1115
+ }
1116
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrMonthpicker, deps: [{ token: LocaleHelperService }, { token: DateNavigationService }, { token: DatepickerFocusService }, { token: i0.ElementRef }, { token: ViewManagerService }, { token: i4.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component }); }
1117
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrMonthpicker, isStandalone: false, selector: "clr-monthpicker", host: { attributes: { "role": "application" }, listeners: { "keydown": "onKeyDown($event)" }, properties: { "class.monthpicker": "true" } }, ngImport: i0, template: `
1118
+ <div class="calendar-header in-monthpicker">
1119
+ <div class="year-view-switcher">
1120
+ <button
1121
+ class="calendar-btn yearpicker-trigger"
1122
+ type="button"
1123
+ (click)="changeToYearView()"
1124
+ [attr.aria-label]="yearAttrString"
1125
+ [attr.title]="yearAttrString"
1126
+ >
1127
+ {{ calendarYear }}
1128
+ </button>
1129
+ </div>
1130
+ <div class="calendar-switchers">
1131
+ <button
1132
+ class="calendar-btn switcher"
1133
+ type="button"
1134
+ (click)="previousYear()"
1135
+ [attr.aria-label]="commonStrings.keys.datepickerPreviousMonth"
1136
+ >
1137
+ <cds-icon shape="angle" direction="left" [attr.title]="commonStrings.keys.datepickerPreviousMonth"></cds-icon>
1138
+ </button>
1139
+ <button
1140
+ class="calendar-btn switcher"
1141
+ type="button"
1142
+ (click)="currentYear()"
1143
+ [attr.aria-label]="commonStrings.keys.datepickerCurrentMonth"
1144
+ >
1145
+ <cds-icon shape="event" [attr.title]="commonStrings.keys.datepickerCurrentMonth"></cds-icon>
1146
+ </button>
1147
+ <button
1148
+ class="calendar-btn switcher"
1149
+ type="button"
1150
+ (click)="nextYear()"
1151
+ [attr.aria-label]="commonStrings.keys.datepickerNextMonth"
1152
+ >
1153
+ <cds-icon shape="angle" direction="right" [attr.title]="commonStrings.keys.datepickerNextMonth"></cds-icon>
1154
+ </button>
1155
+ </div>
1156
+ </div>
1157
+ <div class="months">
1158
+ @for (month of monthNames; track month; let monthIndex = $index) {
1159
+ <button
1160
+ type="button"
1161
+ class="calendar-btn month"
1162
+ (click)="changeMonth(monthIndex)"
1163
+ [class.is-selected]="isSelected(monthIndex)"
1164
+ [class.is-start-range]="getIsRangeStartMonth(monthIndex)"
1165
+ [class.is-end-range]="getIsRangeEndMonth(monthIndex)"
1166
+ [class.in-range]="isInRange(monthIndex)"
1167
+ [attr.tabindex]="getTabIndex(monthIndex)"
1168
+ [class.is-today]="calendarYear === currentCalendarYear && monthIndex === currentCalendarMonth"
1169
+ (mouseenter)="onHover(monthIndex)"
1170
+ >
1171
+ {{ month }}
1172
+ </button>
1173
+ }
1174
+ </div>
1175
+ `, isInline: true, dependencies: [{ kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }] }); }
1176
+ }
1177
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrMonthpicker, decorators: [{
1178
+ type: Component,
1179
+ args: [{
1180
+ selector: 'clr-monthpicker',
1181
+ template: `
1182
+ <div class="calendar-header in-monthpicker">
1183
+ <div class="year-view-switcher">
1184
+ <button
1185
+ class="calendar-btn yearpicker-trigger"
1186
+ type="button"
1187
+ (click)="changeToYearView()"
1188
+ [attr.aria-label]="yearAttrString"
1189
+ [attr.title]="yearAttrString"
1190
+ >
1191
+ {{ calendarYear }}
1192
+ </button>
1193
+ </div>
1194
+ <div class="calendar-switchers">
1195
+ <button
1196
+ class="calendar-btn switcher"
1197
+ type="button"
1198
+ (click)="previousYear()"
1199
+ [attr.aria-label]="commonStrings.keys.datepickerPreviousMonth"
1200
+ >
1201
+ <cds-icon shape="angle" direction="left" [attr.title]="commonStrings.keys.datepickerPreviousMonth"></cds-icon>
1202
+ </button>
1203
+ <button
1204
+ class="calendar-btn switcher"
1205
+ type="button"
1206
+ (click)="currentYear()"
1207
+ [attr.aria-label]="commonStrings.keys.datepickerCurrentMonth"
1208
+ >
1209
+ <cds-icon shape="event" [attr.title]="commonStrings.keys.datepickerCurrentMonth"></cds-icon>
1210
+ </button>
1211
+ <button
1212
+ class="calendar-btn switcher"
1213
+ type="button"
1214
+ (click)="nextYear()"
1215
+ [attr.aria-label]="commonStrings.keys.datepickerNextMonth"
1216
+ >
1217
+ <cds-icon shape="angle" direction="right" [attr.title]="commonStrings.keys.datepickerNextMonth"></cds-icon>
1218
+ </button>
1219
+ </div>
1220
+ </div>
1221
+ <div class="months">
1222
+ @for (month of monthNames; track month; let monthIndex = $index) {
1223
+ <button
1224
+ type="button"
1225
+ class="calendar-btn month"
1226
+ (click)="changeMonth(monthIndex)"
1227
+ [class.is-selected]="isSelected(monthIndex)"
1228
+ [class.is-start-range]="getIsRangeStartMonth(monthIndex)"
1229
+ [class.is-end-range]="getIsRangeEndMonth(monthIndex)"
1230
+ [class.in-range]="isInRange(monthIndex)"
1231
+ [attr.tabindex]="getTabIndex(monthIndex)"
1232
+ [class.is-today]="calendarYear === currentCalendarYear && monthIndex === currentCalendarMonth"
1233
+ (mouseenter)="onHover(monthIndex)"
1234
+ >
1235
+ {{ month }}
1236
+ </button>
1237
+ }
1238
+ </div>
1239
+ `,
1240
+ host: {
1241
+ '[class.monthpicker]': 'true',
1242
+ role: 'application',
1243
+ },
1244
+ standalone: false,
1245
+ }]
1246
+ }], ctorParameters: () => [{ type: LocaleHelperService }, { type: DateNavigationService }, { type: DatepickerFocusService }, { type: i0.ElementRef }, { type: ViewManagerService }, { type: i4.ClrCommonStringsService }], propDecorators: { onKeyDown: [{
1247
+ type: HostListener,
1248
+ args: ['keydown', ['$event']]
1249
+ }] } });
1250
+
1251
+ /*
1252
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1253
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1254
+ * This software is released under MIT license.
1255
+ * The full license information can be found in LICENSE in the root directory of this project.
1256
+ */
1257
+ const YEARS_TO_DISPLAY = 10;
1258
+ class YearRangeModel {
1259
+ constructor(year) {
1260
+ this.year = year;
1261
+ this.yearRange = [];
1262
+ this.generateYearRange();
1263
+ }
1264
+ /**
1265
+ * Gets the number in the middle of the range.
1266
+ */
1267
+ get middleYear() {
1268
+ return this.yearRange[Math.floor(this.yearRange.length / 2)];
1269
+ }
1270
+ /**
1271
+ * Generates the YearRangeModel for the next decade.
1272
+ */
1273
+ nextDecade() {
1274
+ return new YearRangeModel(this.year + 10);
1275
+ }
1276
+ /**
1277
+ * Generates the YearRangeModel for the previous decade.
1278
+ */
1279
+ previousDecade() {
1280
+ return new YearRangeModel(this.year - 10);
1281
+ }
1282
+ /**
1283
+ * Generates the YearRangeModel for the current decade.
1284
+ */
1285
+ currentDecade() {
1286
+ return new YearRangeModel(new Date().getFullYear());
1287
+ }
1288
+ /**
1289
+ * Checks if the value is in the YearRangeModel.
1290
+ */
1291
+ inRange(value) {
1292
+ return this.yearRange.indexOf(value) > -1;
1293
+ }
1294
+ /**
1295
+ * Generates the year range based on the year parameter.
1296
+ * eg: If 2018 is passed the output will be [2010, 2011, ..., 2019]
1297
+ */
1298
+ generateYearRange() {
1299
+ const remainder = this.year % YEARS_TO_DISPLAY;
1300
+ const floor = this.year - remainder;
1301
+ const ceil = floor + YEARS_TO_DISPLAY;
1302
+ this.yearRange = this.generateRange(floor, ceil);
1303
+ }
1304
+ /**
1305
+ * Function which generate a range of numbers from floor to ceil.
1306
+ */
1307
+ generateRange(floor, ceil) {
1308
+ return Array.from({ length: ceil - floor }, (_v, k) => k + floor);
1309
+ }
1310
+ }
1311
+
1312
+ /*
1313
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1314
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1315
+ * This software is released under MIT license.
1316
+ * The full license information can be found in LICENSE in the root directory of this project.
1317
+ */
1318
+ class ClrYearpicker {
1319
+ constructor(_dateNavigationService, _viewManagerService, _datepickerFocusService, _elRef, commonStrings) {
1320
+ this._dateNavigationService = _dateNavigationService;
1321
+ this._viewManagerService = _viewManagerService;
1322
+ this._datepickerFocusService = _datepickerFocusService;
1323
+ this._elRef = _elRef;
1324
+ this.commonStrings = commonStrings;
1325
+ this.yearRangeModel = new YearRangeModel(this.calendarYear);
1326
+ this._focusedYear = this.calendarYear;
1327
+ }
1328
+ get selectedStartYear() {
1329
+ return this._dateNavigationService.selectedDay?.year;
1330
+ }
1331
+ get selectedEndYear() {
1332
+ return this._dateNavigationService.selectedEndDay?.year;
1333
+ }
1334
+ /**
1335
+ * Gets the year which the user is currently on.
1336
+ */
1337
+ get calendarYear() {
1338
+ return this._dateNavigationService.displayedCalendar.year;
1339
+ }
1340
+ isCurrentCalendarYear(year) {
1341
+ return year === new Date().getFullYear();
1342
+ }
1343
+ getIsRangeStartYear(year) {
1344
+ return this._dateNavigationService.isRangePicker && year === this._dateNavigationService.selectedDay?.year;
1345
+ }
1346
+ getIsRangeEndYear(year) {
1347
+ return this._dateNavigationService.isRangePicker && year === this._dateNavigationService.selectedEndDay?.year;
1348
+ }
1349
+ /**
1350
+ * Focuses on the current calendar year when the View is initialized.
1351
+ */
1352
+ ngAfterViewInit() {
1353
+ this._datepickerFocusService.focusCell(this._elRef);
1354
+ }
1355
+ /**
1356
+ * Handles the Keyboard arrow navigation for the yearpicker.
1357
+ */
1358
+ onKeyDown(event) {
1359
+ // NOTE: Didn't move this to the date navigation service because
1360
+ // the logic is fairly simple and it didn't make sense for me
1361
+ // to create extra observables just to move this logic to the service.
1362
+ if (event) {
1363
+ const key = event.key;
1364
+ if (key === Keys.ArrowUp) {
1365
+ event.preventDefault();
1366
+ this.incrementFocusYearBy(-2);
1367
+ }
1368
+ else if (key === Keys.ArrowDown) {
1369
+ event.preventDefault();
1370
+ this.incrementFocusYearBy(2);
1371
+ }
1372
+ else if (key === Keys.ArrowRight) {
1373
+ event.preventDefault();
1374
+ this.incrementFocusYearBy(1);
1375
+ }
1376
+ else if (key === Keys.ArrowLeft) {
1377
+ event.preventDefault();
1378
+ this.incrementFocusYearBy(-1);
1379
+ }
1380
+ }
1381
+ }
1382
+ /**
1383
+ * Calls the DateNavigationService to update the year value of the calendar.
1384
+ * Also changes the view to the daypicker.
1385
+ */
1386
+ changeYear(year) {
1387
+ this._dateNavigationService.changeYear(year);
1388
+ this._viewManagerService.changeToDayView();
1389
+ }
1390
+ /**
1391
+ * Calls the DateNavigationService to update the hovered year value of the calendar
1392
+ */
1393
+ onHover(year) {
1394
+ this._dateNavigationService.hoveredYear = year;
1395
+ }
1396
+ /**
1397
+ * Updates the YearRangeModel to the previous decade.
1398
+ */
1399
+ previousDecade() {
1400
+ this.yearRangeModel = this.yearRangeModel.previousDecade();
1401
+ // Year in the yearpicker is not focused because while navigating to a different decade,
1402
+ // you want the focus to remain on the decade switcher arrows.
1403
+ }
1404
+ /**
1405
+ * Updates the YearRangeModel to the current decade.
1406
+ */
1407
+ currentDecade() {
1408
+ if (!this.yearRangeModel.inRange(this._dateNavigationService.today.year)) {
1409
+ this.yearRangeModel = this.yearRangeModel.currentDecade();
1410
+ }
1411
+ this._datepickerFocusService.focusCell(this._elRef);
1412
+ }
1413
+ /**
1414
+ * Updates the YearRangeModel to the next decade.
1415
+ */
1416
+ nextDecade() {
1417
+ this.yearRangeModel = this.yearRangeModel.nextDecade();
1418
+ // Year in the yearpicker is not focused because while navigating to a different decade,
1419
+ // you want the focus to remain on the decade switcher arrows.
1420
+ }
1421
+ /**
1422
+ * Compares the year passed to the focused year and returns the tab index.
1423
+ */
1424
+ getTabIndex(year) {
1425
+ if (!this.yearRangeModel.inRange(this._focusedYear)) {
1426
+ if (this.yearRangeModel.inRange(this.calendarYear)) {
1427
+ this._focusedYear = this.calendarYear;
1428
+ }
1429
+ else if (this.yearRangeModel.inRange(this.selectedEndYear)) {
1430
+ this._focusedYear = this.selectedEndYear;
1431
+ }
1432
+ else {
1433
+ this._focusedYear = this.yearRangeModel.middleYear;
1434
+ }
1435
+ }
1436
+ return this._focusedYear === year ? 0 : -1;
1437
+ }
1438
+ /**
1439
+ * Applicable only to date range picker
1440
+ * Compares the year passed is in between the start and end date range
1441
+ */
1442
+ isInRange(year) {
1443
+ if (!this._dateNavigationService.isRangePicker) {
1444
+ return false;
1445
+ }
1446
+ if (this._dateNavigationService.selectedDay?.year && this.selectedEndYear) {
1447
+ return year > this.selectedStartYear && year < this.selectedEndYear;
1448
+ }
1449
+ else if (this._dateNavigationService.selectedDay?.year && !this.selectedEndYear) {
1450
+ return year > this.selectedStartYear && year < this._dateNavigationService.hoveredYear;
1451
+ }
1452
+ else {
1453
+ return false;
1454
+ }
1455
+ }
1456
+ changeToDayView() {
1457
+ this._viewManagerService.changeToDayView();
1458
+ }
1459
+ /**
1460
+ * Increments the focus year by the value passed. Updates the YearRangeModel if the
1461
+ * new value is not in the current decade.
1462
+ */
1463
+ incrementFocusYearBy(value) {
1464
+ this._focusedYear = this._focusedYear + value;
1465
+ if (!this.yearRangeModel.inRange(this._focusedYear)) {
1466
+ if (value > 0) {
1467
+ this.yearRangeModel = this.yearRangeModel.nextDecade();
1468
+ }
1469
+ else {
1470
+ this.yearRangeModel = this.yearRangeModel.previousDecade();
1471
+ }
1472
+ }
1473
+ this._datepickerFocusService.focusCell(this._elRef);
1474
+ }
1475
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrYearpicker, deps: [{ token: DateNavigationService }, { token: ViewManagerService }, { token: DatepickerFocusService }, { token: i0.ElementRef }, { token: i4.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component }); }
1476
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrYearpicker, isStandalone: false, selector: "clr-yearpicker", host: { attributes: { "role": "application" }, listeners: { "keydown": "onKeyDown($event)" }, properties: { "class.yearpicker": "true" } }, ngImport: i0, template: `
1477
+ <div class="calendar-header">
1478
+ <div class="calendar-pickers">
1479
+ <button class="calendar-btn yearpicker-trigger year-range" type="button" (click)="changeToDayView()">
1480
+ {{ yearRangeModel.yearRange[0] }} - {{ yearRangeModel.yearRange[yearRangeModel.yearRange.length - 1] }}
1481
+ </button>
1482
+ </div>
1483
+ <div class="year-switchers">
1484
+ <button
1485
+ class="calendar-btn switcher"
1486
+ type="button"
1487
+ (click)="previousDecade()"
1488
+ [attr.aria-label]="commonStrings.keys.datepickerPreviousDecade"
1489
+ >
1490
+ <cds-icon
1491
+ shape="angle"
1492
+ direction="left"
1493
+ [attr.title]="commonStrings.keys.datepickerPreviousDecade"
1494
+ ></cds-icon>
1495
+ </button>
1496
+ <button
1497
+ class="calendar-btn switcher"
1498
+ type="button"
1499
+ (click)="currentDecade()"
1500
+ [attr.aria-label]="commonStrings.keys.datepickerCurrentDecade"
1501
+ >
1502
+ <cds-icon shape="event" [attr.title]="commonStrings.keys.datepickerCurrentDecade"></cds-icon>
1503
+ </button>
1504
+ <button
1505
+ class="calendar-btn switcher"
1506
+ type="button"
1507
+ (click)="nextDecade()"
1508
+ [attr.aria-label]="commonStrings.keys.datepickerNextDecade"
1509
+ >
1510
+ <cds-icon shape="angle" direction="right" [attr.title]="commonStrings.keys.datepickerNextDecade"></cds-icon>
1511
+ </button>
1512
+ </div>
1513
+ </div>
1514
+
1515
+ <div class="years">
1516
+ @for (year of yearRangeModel.yearRange; track year) {
1517
+ <button
1518
+ type="button"
1519
+ class="calendar-btn year"
1520
+ [attr.tabindex]="getTabIndex(year)"
1521
+ [class.is-selected]="year === selectedStartYear || year === selectedEndYear"
1522
+ [class.is-start-range]="getIsRangeStartYear(year)"
1523
+ [class.is-end-range]="getIsRangeEndYear(year)"
1524
+ [class.in-range]="isInRange(year)"
1525
+ [class.is-today]="isCurrentCalendarYear(year)"
1526
+ (click)="changeYear(year)"
1527
+ (mouseenter)="onHover(year)"
1528
+ >
1529
+ {{ year }}
1530
+ </button>
1531
+ }
1532
+ </div>
1533
+ `, isInline: true, dependencies: [{ kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }] }); }
1534
+ }
1535
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrYearpicker, decorators: [{
1536
+ type: Component,
1537
+ args: [{
1538
+ selector: 'clr-yearpicker',
1539
+ template: `
1540
+ <div class="calendar-header">
1541
+ <div class="calendar-pickers">
1542
+ <button class="calendar-btn yearpicker-trigger year-range" type="button" (click)="changeToDayView()">
1543
+ {{ yearRangeModel.yearRange[0] }} - {{ yearRangeModel.yearRange[yearRangeModel.yearRange.length - 1] }}
1544
+ </button>
1545
+ </div>
1546
+ <div class="year-switchers">
1547
+ <button
1548
+ class="calendar-btn switcher"
1549
+ type="button"
1550
+ (click)="previousDecade()"
1551
+ [attr.aria-label]="commonStrings.keys.datepickerPreviousDecade"
1552
+ >
1553
+ <cds-icon
1554
+ shape="angle"
1555
+ direction="left"
1556
+ [attr.title]="commonStrings.keys.datepickerPreviousDecade"
1557
+ ></cds-icon>
1558
+ </button>
1559
+ <button
1560
+ class="calendar-btn switcher"
1561
+ type="button"
1562
+ (click)="currentDecade()"
1563
+ [attr.aria-label]="commonStrings.keys.datepickerCurrentDecade"
1564
+ >
1565
+ <cds-icon shape="event" [attr.title]="commonStrings.keys.datepickerCurrentDecade"></cds-icon>
1566
+ </button>
1567
+ <button
1568
+ class="calendar-btn switcher"
1569
+ type="button"
1570
+ (click)="nextDecade()"
1571
+ [attr.aria-label]="commonStrings.keys.datepickerNextDecade"
1572
+ >
1573
+ <cds-icon shape="angle" direction="right" [attr.title]="commonStrings.keys.datepickerNextDecade"></cds-icon>
1574
+ </button>
1575
+ </div>
1576
+ </div>
1577
+
1578
+ <div class="years">
1579
+ @for (year of yearRangeModel.yearRange; track year) {
1580
+ <button
1581
+ type="button"
1582
+ class="calendar-btn year"
1583
+ [attr.tabindex]="getTabIndex(year)"
1584
+ [class.is-selected]="year === selectedStartYear || year === selectedEndYear"
1585
+ [class.is-start-range]="getIsRangeStartYear(year)"
1586
+ [class.is-end-range]="getIsRangeEndYear(year)"
1587
+ [class.in-range]="isInRange(year)"
1588
+ [class.is-today]="isCurrentCalendarYear(year)"
1589
+ (click)="changeYear(year)"
1590
+ (mouseenter)="onHover(year)"
1591
+ >
1592
+ {{ year }}
1593
+ </button>
1594
+ }
1595
+ </div>
1596
+ `,
1597
+ host: {
1598
+ '[class.yearpicker]': 'true',
1599
+ role: 'application',
1600
+ },
1601
+ standalone: false,
1602
+ }]
1603
+ }], ctorParameters: () => [{ type: DateNavigationService }, { type: ViewManagerService }, { type: DatepickerFocusService }, { type: i0.ElementRef }, { type: i4.ClrCommonStringsService }], propDecorators: { onKeyDown: [{
1604
+ type: HostListener,
1605
+ args: ['keydown', ['$event']]
1606
+ }] } });
1607
+
1608
+ /*
1609
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1610
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1611
+ * This software is released under MIT license.
1612
+ * The full license information can be found in LICENSE in the root directory of this project.
1613
+ */
1614
+ class DayViewModel {
1615
+ constructor(dayModel, isTodaysDate = false, isExcluded = false, isDisabled = false, isSelected = false, isFocusable = false, isRangeStartDay = false, isRangeEndDay = false) {
1616
+ this.dayModel = dayModel;
1617
+ this.isTodaysDate = isTodaysDate;
1618
+ this.isExcluded = isExcluded;
1619
+ this.isDisabled = isDisabled;
1620
+ this.isSelected = isSelected;
1621
+ this.isFocusable = isFocusable;
1622
+ this.isRangeStartDay = isRangeStartDay;
1623
+ this.isRangeEndDay = isRangeEndDay;
1624
+ }
1625
+ /**
1626
+ * Gets the tab index based on the isFocusable flag.
1627
+ */
1628
+ get tabIndex() {
1629
+ return this.isFocusable ? 0 : -1;
1630
+ }
1631
+ }
1632
+
1633
+ /*
1634
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1635
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1636
+ * This software is released under MIT license.
1637
+ * The full license information can be found in LICENSE in the root directory of this project.
1638
+ */
1639
+ class CalendarViewModel {
1640
+ constructor(calendar, selectedDay, selectedEndDay, focusableDay, today, firstDayOfWeek, excludedDates) {
1641
+ this.calendar = calendar;
1642
+ this.selectedDay = selectedDay;
1643
+ this.selectedEndDay = selectedEndDay;
1644
+ this.focusableDay = focusableDay;
1645
+ this.today = today;
1646
+ this.firstDayOfWeek = firstDayOfWeek;
1647
+ this.excludedDates = excludedDates;
1648
+ this.currMonthDayViews = [];
1649
+ this.initializeCalendarView();
1650
+ }
1651
+ /**
1652
+ * DayViewModel matrix. Size 6x7
1653
+ */
1654
+ get calendarView() {
1655
+ return this._calendarView;
1656
+ }
1657
+ /**
1658
+ * Updates the focusable day in the calendar.
1659
+ */
1660
+ updateFocusableDay(day) {
1661
+ this.setFocusableFlag(this.focusableDay, false);
1662
+ this.setFocusableFlag(day, true);
1663
+ this.focusableDay = day;
1664
+ }
1665
+ /**
1666
+ * Updates the selected day in the calendar
1667
+ */
1668
+ updateSelectedDay(day) {
1669
+ this.setSelectedDay(this.selectedDay, false);
1670
+ this.selectedDay = day;
1671
+ this.setSelectedDay(day, true);
1672
+ }
1673
+ /**
1674
+ * Updates the selected end day in the calendar
1675
+ */
1676
+ updateSelectedEndDay(day) {
1677
+ this.setSelectedDay(this.selectedEndDay, false);
1678
+ this.selectedEndDay = day;
1679
+ this.setSelectedDay(day, true);
1680
+ }
1681
+ /**
1682
+ * Generates a 6x7 matrix of DayViewModel based on the Calendar.
1683
+ * The 6x7 matrix is structured according to the first day of the week.
1684
+ * 6 rows to accommodate months which might have dates spanning over 6 weeks.
1685
+ * 7 columns because there are 7 days in a week :P :D
1686
+ */
1687
+ initializeCalendarView() {
1688
+ // Generate prev and next month calendar models.
1689
+ const prevMonthCalendar = this.calendar.previousMonth();
1690
+ const nextMonthCalendar = this.calendar.nextMonth();
1691
+ // Get no of days from prev and next months.
1692
+ const daysFromPrevMonthInCalView = this.numDaysFromPrevMonthInCalView(this.calendar.year, this.calendar.month);
1693
+ const daysFromNextMonthInCalView = TOTAL_DAYS_IN_DAYS_VIEW - (this.calendar.days.length + daysFromPrevMonthInCalView);
1694
+ // Generate prev, curr and next day view models
1695
+ let prevMonthDayViews = [];
1696
+ let nextMonthDayViews = [];
1697
+ if (daysFromPrevMonthInCalView > 0) {
1698
+ prevMonthDayViews = this.generateDayViewModels(prevMonthCalendar.days.slice(-1 * daysFromPrevMonthInCalView), true, false);
1699
+ }
1700
+ this.currMonthDayViews = this.generateDayViewModels(this.calendar.days, false, true);
1701
+ if (daysFromNextMonthInCalView > 0) {
1702
+ nextMonthDayViews = this.generateDayViewModels(nextMonthCalendar.days.slice(0, daysFromNextMonthInCalView), true, false);
1703
+ }
1704
+ // Generate calendar view and initialize flags
1705
+ this._calendarView = this.generateCalendarView(prevMonthDayViews, this.currMonthDayViews, nextMonthDayViews);
1706
+ this.initializeSelectedDay();
1707
+ this.initializeFocusableDay();
1708
+ }
1709
+ isDateExcluded(date) {
1710
+ const { minDate, maxDate } = this.excludedDates;
1711
+ const from = minDate.toComparisonString();
1712
+ const to = maxDate.toComparisonString();
1713
+ const today = date.toComparisonString();
1714
+ return !(today >= from && today <= to);
1715
+ }
1716
+ /**
1717
+ * Generates a DayViewModel array based on the DayModel passed
1718
+ */
1719
+ generateDayViewModels(days, isExcluded, isCurrentCalendar) {
1720
+ const dayViews = days.map(day => {
1721
+ return new DayViewModel(day, false, isExcluded, this.isDateExcluded(day), false, false);
1722
+ });
1723
+ if (isCurrentCalendar && this.calendar.isDayInCalendar(this.today)) {
1724
+ dayViews[this.today.date - 1].isTodaysDate = true;
1725
+ }
1726
+ return dayViews;
1727
+ }
1728
+ /**
1729
+ * Gets the first day of the current month to figure out how many dates of previous month
1730
+ * are needed to complete the Calendar View based on the first day of the week.
1731
+ * eg: Assuming locale en-US, the first day of the week is Sunday,
1732
+ * if first day of the current month lands on Wednesday, then
1733
+ * (this.getDay function would return 3 since
1734
+ * first day of the week is 0), we need the 3 days from the previous month.
1735
+ */
1736
+ numDaysFromPrevMonthInCalView(currentYear, currentMonth) {
1737
+ const firstDayOfCurrMonth = getDay(currentYear, currentMonth, 1);
1738
+ if (firstDayOfCurrMonth >= this.firstDayOfWeek) {
1739
+ return firstDayOfCurrMonth - this.firstDayOfWeek;
1740
+ }
1741
+ else {
1742
+ return NO_OF_DAYS_IN_A_WEEK + firstDayOfCurrMonth - this.firstDayOfWeek;
1743
+ }
1744
+ }
1745
+ /**
1746
+ * Checks if the Day passed is in the CalendarView.
1747
+ */
1748
+ isDayInCalendarView(day) {
1749
+ if (!this.calendar.isDayInCalendar(day)) {
1750
+ return false;
1751
+ }
1752
+ return true;
1753
+ }
1754
+ /**
1755
+ * Using the DayViewModels from the previous, current and next month, this function
1756
+ * generates the CalendarView.
1757
+ */
1758
+ generateCalendarView(prev, curr, next) {
1759
+ const combinationArr = [...prev, ...curr, ...next];
1760
+ const calendarView = [];
1761
+ for (let i = 0; i < NO_OF_ROWS_IN_CALENDAR_VIEW; i++) {
1762
+ calendarView[i] = combinationArr.slice(i * NO_OF_DAYS_IN_A_WEEK, (i + 1) * NO_OF_DAYS_IN_A_WEEK);
1763
+ }
1764
+ return calendarView;
1765
+ }
1766
+ /**
1767
+ * Initialize the selected day if the day is in the calendar.
1768
+ */
1769
+ initializeSelectedDay() {
1770
+ this.setSelectedDay(this.selectedDay, true);
1771
+ this.setSelectedDay(this.selectedEndDay, true);
1772
+ }
1773
+ /**
1774
+ * Initializes the focusable day if the day is in the calendar. If focusable day is not set, then
1775
+ * we check for the selected day. If selected day is not set then check if today is in the current
1776
+ * calendar. If not then just set the 15th of the current calendar month.
1777
+ */
1778
+ initializeFocusableDay() {
1779
+ if (this.focusableDay && this.isDayInCalendarView(this.focusableDay)) {
1780
+ this.setFocusableFlag(this.focusableDay, true);
1781
+ }
1782
+ else if (this.selectedDay && this.isDayInCalendarView(this.selectedDay)) {
1783
+ this.setFocusableFlag(this.selectedDay, true);
1784
+ this.focusableDay = this.selectedDay.clone();
1785
+ }
1786
+ else if (this.selectedEndDay && this.isDayInCalendarView(this.selectedEndDay)) {
1787
+ this.setFocusableFlag(this.selectedEndDay, true);
1788
+ this.focusableDay = this.selectedEndDay.clone();
1789
+ }
1790
+ else if (this.isDayInCalendarView(this.today)) {
1791
+ this.setFocusableFlag(this.today, true);
1792
+ this.focusableDay = this.today.clone();
1793
+ }
1794
+ else {
1795
+ this.focusableDay = new DayModel(this.calendar.year, this.calendar.month, 15);
1796
+ this.setFocusableFlag(this.focusableDay, true);
1797
+ }
1798
+ }
1799
+ setFocusableFlag(day, flag) {
1800
+ if (day) {
1801
+ this.currMonthDayViews[day.date - 1].isFocusable = flag;
1802
+ }
1803
+ }
1804
+ setSelectedDay(day, flag) {
1805
+ if (day && this.isDayInCalendarView(day)) {
1806
+ this.currMonthDayViews[day?.date - 1].isSelected = flag;
1807
+ }
1808
+ }
1809
+ }
1810
+
1811
+ /*
1812
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1813
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1814
+ * This software is released under MIT license.
1815
+ * The full license information can be found in LICENSE in the root directory of this project.
1816
+ */
1817
+ class ClrDay {
1818
+ constructor(_dateNavigationService, commonStrings) {
1819
+ this._dateNavigationService = _dateNavigationService;
1820
+ this.commonStrings = commonStrings;
1821
+ this.onSelectDay = new EventEmitter();
1822
+ }
1823
+ /**
1824
+ * DayViewModel input which is used to build the Day View.
1825
+ */
1826
+ get dayView() {
1827
+ return this._dayView;
1828
+ }
1829
+ set dayView(day) {
1830
+ this._dayView = day;
1831
+ }
1832
+ get dayString() {
1833
+ return this.dayView.isSelected
1834
+ ? this.commonStrings.parse(this.commonStrings.keys.datepickerSelectedLabel, {
1835
+ FULL_DATE: this._dayView.dayModel.toDateString(),
1836
+ })
1837
+ : this._dayView.dayModel.toDateString();
1838
+ }
1839
+ get isRangeStartDay() {
1840
+ return (this._dateNavigationService.isRangePicker &&
1841
+ this.dayView?.dayModel?.toComparisonString() === this._dateNavigationService.selectedDay?.toComparisonString());
1842
+ }
1843
+ get isRangeEndDay() {
1844
+ return (this._dateNavigationService.isRangePicker &&
1845
+ this.dayView?.dayModel?.toComparisonString() === this._dateNavigationService.selectedEndDay?.toComparisonString());
1846
+ }
1847
+ /**
1848
+ * Calls the DateNavigationService to update the hovered day value of the calendar
1849
+ */
1850
+ hoverListener() {
1851
+ if (!this.dayView.isDisabled) {
1852
+ this._dateNavigationService.hoveredDay = this.dayView.dayModel;
1853
+ }
1854
+ }
1855
+ /**
1856
+ * Updates the focusedDay in the DateNavigationService when the ClrDay is focused.
1857
+ */
1858
+ onDayViewFocus() {
1859
+ this._dateNavigationService.focusedDay = this.dayView.dayModel;
1860
+ }
1861
+ /**
1862
+ * Updates the selectedDay when the ClrDay is selected and closes the datepicker popover.
1863
+ */
1864
+ selectDay() {
1865
+ if (this.dayView.isDisabled) {
1866
+ return;
1867
+ }
1868
+ const day = this.dayView.dayModel;
1869
+ this.onSelectDay.emit(day);
1870
+ }
1871
+ /**
1872
+ * Applicable only to date range picker
1873
+ * Compares whether the day is in between the start and end date range
1874
+ */
1875
+ isInRange() {
1876
+ if (!this._dateNavigationService.isRangePicker) {
1877
+ return false;
1878
+ }
1879
+ if (this._dateNavigationService.selectedDay && this._dateNavigationService.selectedEndDay) {
1880
+ return (this._dayView.dayModel?.isAfter(this._dateNavigationService.selectedDay) &&
1881
+ this._dayView.dayModel?.isBefore(this._dateNavigationService.selectedEndDay));
1882
+ }
1883
+ else if (this._dateNavigationService.selectedDay && !this._dateNavigationService.selectedEndDay) {
1884
+ return (this._dayView.dayModel?.isAfter(this._dateNavigationService.selectedDay) &&
1885
+ this._dayView.dayModel?.isBefore(this._dateNavigationService.hoveredDay, true));
1886
+ }
1887
+ else {
1888
+ return false;
1889
+ }
1890
+ }
1891
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDay, deps: [{ token: DateNavigationService }, { token: i4.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component }); }
1892
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrDay, isStandalone: false, selector: "clr-day", inputs: { dayView: ["clrDayView", "dayView"] }, outputs: { onSelectDay: "selectDay" }, host: { listeners: { "mouseenter": "hoverListener()" }, properties: { "class.day": "true" } }, ngImport: i0, template: `
1893
+ <button
1894
+ class="day-btn"
1895
+ type="button"
1896
+ [class.is-today]="dayView.isTodaysDate"
1897
+ [class.is-excluded]="dayView.isExcluded"
1898
+ [class.is-disabled]="dayView.isDisabled"
1899
+ [class.is-selected]="dayView.isSelected"
1900
+ [class.in-range]="isInRange()"
1901
+ [class.is-start-range]="isRangeStartDay"
1902
+ [class.is-end-range]="isRangeEndDay"
1903
+ [attr.tabindex]="dayView.tabIndex"
1904
+ (click)="selectDay()"
1905
+ (focus)="onDayViewFocus()"
1906
+ [attr.aria-current]="dayView.isTodaysDate ? 'date' : 'false'"
1907
+ [attr.aria-label]="dayString"
1908
+ [attr.aria-selected]="dayView.isSelected"
1909
+ >
1910
+ {{ dayView.dayModel.date }}
1911
+ </button>
1912
+ `, isInline: true }); }
1913
+ }
1914
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDay, decorators: [{
1915
+ type: Component,
1916
+ args: [{
1917
+ selector: 'clr-day',
1918
+ template: `
1919
+ <button
1920
+ class="day-btn"
1921
+ type="button"
1922
+ [class.is-today]="dayView.isTodaysDate"
1923
+ [class.is-excluded]="dayView.isExcluded"
1924
+ [class.is-disabled]="dayView.isDisabled"
1925
+ [class.is-selected]="dayView.isSelected"
1926
+ [class.in-range]="isInRange()"
1927
+ [class.is-start-range]="isRangeStartDay"
1928
+ [class.is-end-range]="isRangeEndDay"
1929
+ [attr.tabindex]="dayView.tabIndex"
1930
+ (click)="selectDay()"
1931
+ (focus)="onDayViewFocus()"
1932
+ [attr.aria-current]="dayView.isTodaysDate ? 'date' : 'false'"
1933
+ [attr.aria-label]="dayString"
1934
+ [attr.aria-selected]="dayView.isSelected"
1935
+ >
1936
+ {{ dayView.dayModel.date }}
1937
+ </button>
1938
+ `,
1939
+ host: { '[class.day]': 'true' },
1940
+ standalone: false,
1941
+ }]
1942
+ }], ctorParameters: () => [{ type: DateNavigationService }, { type: i4.ClrCommonStringsService }], propDecorators: { onSelectDay: [{
1943
+ type: Output,
1944
+ args: ['selectDay']
1945
+ }], dayView: [{
1946
+ type: Input,
1947
+ args: ['clrDayView']
1948
+ }], hoverListener: [{
1949
+ type: HostListener,
1950
+ args: ['mouseenter']
1951
+ }] } });
1952
+
1953
+ /*
1954
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
1955
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
1956
+ * This software is released under MIT license.
1957
+ * The full license information can be found in LICENSE in the root directory of this project.
1958
+ */
1959
+ class ClrCalendar {
1960
+ constructor(_localeHelperService, _dateNavigationService, _datepickerFocusService, _dateIOService, _elRef, _dateFormControlService, _popoverService) {
1961
+ this._localeHelperService = _localeHelperService;
1962
+ this._dateNavigationService = _dateNavigationService;
1963
+ this._datepickerFocusService = _datepickerFocusService;
1964
+ this._dateIOService = _dateIOService;
1965
+ this._elRef = _elRef;
1966
+ this._dateFormControlService = _dateFormControlService;
1967
+ this._popoverService = _popoverService;
1968
+ this._subs = [];
1969
+ this.generateCalendarView();
1970
+ this.initializeSubscriptions();
1971
+ }
1972
+ /**
1973
+ * Gets the locale days according to the TranslationWidth.Narrow format.
1974
+ */
1975
+ get localeDays() {
1976
+ return this._localeHelperService.localeDays;
1977
+ }
1978
+ get calendar() {
1979
+ return this._dateNavigationService.displayedCalendar;
1980
+ }
1981
+ get selectedDay() {
1982
+ return this._dateNavigationService.selectedDay;
1983
+ }
1984
+ get selectedEndDay() {
1985
+ return this._dateNavigationService.selectedEndDay;
1986
+ }
1987
+ get focusedDay() {
1988
+ return this._dateNavigationService.focusedDay;
1989
+ }
1990
+ get today() {
1991
+ return this._dateNavigationService.today;
1992
+ }
1993
+ /**
1994
+ * Focuses on the focusable day when the Calendar View is initialized.
1995
+ */
1996
+ ngAfterViewInit() {
1997
+ this._datepickerFocusService.focusCell(this._elRef);
1998
+ }
1999
+ /**
2000
+ * Unsubscribe from subscriptions.
2001
+ */
2002
+ ngOnDestroy() {
2003
+ this._subs.forEach((sub) => sub.unsubscribe());
2004
+ }
2005
+ /**
2006
+ * Delegates Keyboard arrow navigation to the DateNavigationService.
2007
+ */
2008
+ onKeyDown(event) {
2009
+ if (event && this.focusedDay) {
2010
+ switch (event.key) {
2011
+ case Keys.ArrowUp:
2012
+ event.preventDefault();
2013
+ this._dateNavigationService.incrementFocusDay(-1 * NO_OF_DAYS_IN_A_WEEK);
2014
+ break;
2015
+ case Keys.ArrowDown:
2016
+ event.preventDefault();
2017
+ this._dateNavigationService.incrementFocusDay(NO_OF_DAYS_IN_A_WEEK);
2018
+ break;
2019
+ case Keys.ArrowLeft:
2020
+ event.preventDefault();
2021
+ this._dateNavigationService.incrementFocusDay(-1);
2022
+ break;
2023
+ case Keys.ArrowRight:
2024
+ event.preventDefault();
2025
+ this._dateNavigationService.incrementFocusDay(1);
2026
+ break;
2027
+ default:
2028
+ break; // No default case. ESLint x-(
2029
+ }
2030
+ }
2031
+ }
2032
+ setSelectedDay(day) {
2033
+ const hasActionButtons = this._dateNavigationService.hasActionButtons;
2034
+ const selectedDates = this.updateCalendarViewModal(day);
2035
+ this._dateNavigationService.notifySelectedDayChanged(selectedDates, { emitEvent: !hasActionButtons });
2036
+ if (!hasActionButtons) {
2037
+ this._dateFormControlService.markAsDirty();
2038
+ this.validateAndCloseDatePicker();
2039
+ }
2040
+ }
2041
+ /**
2042
+ * Initialize subscriptions to:
2043
+ * 1. update the calendar view model.
2044
+ * 2. update the focusable day in the calendar view model.
2045
+ * 3. focus on the focusable day in the calendar.
2046
+ */
2047
+ initializeSubscriptions() {
2048
+ this._subs.push(this._dateNavigationService.displayedCalendarChange.subscribe(() => {
2049
+ this.generateCalendarView();
2050
+ }));
2051
+ this._subs.push(this._dateNavigationService.focusedDayChange.subscribe((focusedDay) => {
2052
+ this.calendarViewModel.updateFocusableDay(focusedDay);
2053
+ }));
2054
+ this._subs.push(this._dateNavigationService.focusOnCalendarChange.subscribe(() => {
2055
+ this._datepickerFocusService.focusCell(this._elRef);
2056
+ }));
2057
+ this._subs.push(this._dateNavigationService.refreshCalendarView.subscribe(() => {
2058
+ this.refreshCalendarViewModal();
2059
+ }));
2060
+ }
2061
+ validateAndCloseDatePicker() {
2062
+ if ((this._dateNavigationService.isRangePicker &&
2063
+ this._dateNavigationService.selectedDay &&
2064
+ this._dateNavigationService.selectedEndDay) ||
2065
+ (!this._dateNavigationService.isRangePicker && this._dateNavigationService.selectedDay)) {
2066
+ this._popoverService.open = false;
2067
+ }
2068
+ }
2069
+ updateCalendarViewModal(day) {
2070
+ const startDate = this.calendarViewModel.selectedDay || null, isRangePicker = this._dateNavigationService.isRangePicker;
2071
+ let endDate = this.calendarViewModel.selectedEndDay || null;
2072
+ if (isRangePicker) {
2073
+ if (!startDate || (!!startDate && !!endDate) || (!!startDate && day?.isBefore(startDate))) {
2074
+ this.calendarViewModel.updateSelectedDay(day);
2075
+ if (endDate) {
2076
+ endDate = undefined;
2077
+ this.calendarViewModel.updateSelectedEndDay(endDate);
2078
+ }
2079
+ }
2080
+ else {
2081
+ this.calendarViewModel.updateSelectedEndDay(day);
2082
+ }
2083
+ }
2084
+ else {
2085
+ this.calendarViewModel.updateSelectedDay(day);
2086
+ }
2087
+ return isRangePicker
2088
+ ? { startDate: this.calendarViewModel.selectedDay, endDate: this.calendarViewModel.selectedEndDay }
2089
+ : this.calendarViewModel.selectedDay;
2090
+ }
2091
+ refreshCalendarViewModal() {
2092
+ this.calendarViewModel.updateSelectedDay(this._dateNavigationService.selectedDay);
2093
+ if (this._dateNavigationService.isRangePicker) {
2094
+ this.calendarViewModel.updateSelectedEndDay(this._dateNavigationService.selectedEndDay);
2095
+ }
2096
+ }
2097
+ /**
2098
+ * Generates the Calendar View based on the calendar retrieved from the DateNavigationService.
2099
+ */
2100
+ generateCalendarView() {
2101
+ this.calendarViewModel = new CalendarViewModel(this.calendar, this.selectedDay, this.selectedEndDay, this.focusedDay, this.today, this._localeHelperService.firstDayOfWeek, this._dateIOService.disabledDates);
2102
+ }
2103
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrCalendar, deps: [{ token: LocaleHelperService }, { token: DateNavigationService }, { token: DatepickerFocusService }, { token: DateIOService }, { token: i0.ElementRef }, { token: DateFormControlService }, { token: i1.ClrPopoverService }], target: i0.ɵɵFactoryTarget.Component }); }
2104
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrCalendar, isStandalone: false, selector: "clr-calendar", host: { listeners: { "keydown": "onKeyDown($event)" } }, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<table class=\"calendar-table\" role=\"presentation\">\n <tr class=\"calendar-row weekdays\">\n @for (day of localeDays; track day) {\n <th class=\"calendar-cell weekday\">\n <span [attr.aria-label]=\"day.day\">{{day.narrow}}</span>\n </th>\n }\n </tr>\n @for (row of calendarViewModel.calendarView; track row) {\n <tr class=\"calendar-row\">\n @for (dayView of row; track dayView) {\n <td class=\"calendar-cell\">\n <clr-day [clrDayView]=\"dayView\" (selectDay)=\"setSelectedDay($event)\"></clr-day>\n </td>\n }\n </tr>\n }\n</table>\n", dependencies: [{ kind: "component", type: ClrDay, selector: "clr-day", inputs: ["clrDayView"], outputs: ["selectDay"] }] }); }
2105
+ }
2106
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrCalendar, decorators: [{
2107
+ type: Component,
2108
+ args: [{ selector: 'clr-calendar', standalone: false, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<table class=\"calendar-table\" role=\"presentation\">\n <tr class=\"calendar-row weekdays\">\n @for (day of localeDays; track day) {\n <th class=\"calendar-cell weekday\">\n <span [attr.aria-label]=\"day.day\">{{day.narrow}}</span>\n </th>\n }\n </tr>\n @for (row of calendarViewModel.calendarView; track row) {\n <tr class=\"calendar-row\">\n @for (dayView of row; track dayView) {\n <td class=\"calendar-cell\">\n <clr-day [clrDayView]=\"dayView\" (selectDay)=\"setSelectedDay($event)\"></clr-day>\n </td>\n }\n </tr>\n }\n</table>\n" }]
2109
+ }], ctorParameters: () => [{ type: LocaleHelperService }, { type: DateNavigationService }, { type: DatepickerFocusService }, { type: DateIOService }, { type: i0.ElementRef }, { type: DateFormControlService }, { type: i1.ClrPopoverService }], propDecorators: { onKeyDown: [{
2110
+ type: HostListener,
2111
+ args: ['keydown', ['$event']]
2112
+ }] } });
2113
+
2114
+ /*
2115
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2116
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2117
+ * This software is released under MIT license.
2118
+ * The full license information can be found in LICENSE in the root directory of this project.
2119
+ */
2120
+ class ClrDaypicker {
2121
+ constructor(_viewManagerService, _dateNavigationService, _localeHelperService, commonStrings) {
2122
+ this._viewManagerService = _viewManagerService;
2123
+ this._dateNavigationService = _dateNavigationService;
2124
+ this._localeHelperService = _localeHelperService;
2125
+ this.commonStrings = commonStrings;
2126
+ }
2127
+ get monthAttrString() {
2128
+ return this.commonStrings.parse(this.commonStrings.keys.datepickerSelectMonthText, {
2129
+ CALENDAR_MONTH: this.calendarMonth,
2130
+ });
2131
+ }
2132
+ get yearAttrString() {
2133
+ return this.commonStrings.parse(this.commonStrings.keys.datepickerSelectYearText, {
2134
+ CALENDAR_YEAR: this.calendarYear.toString(),
2135
+ });
2136
+ }
2137
+ /**
2138
+ * Returns the month value of the calendar in the TranslationWidth.Abbreviated format.
2139
+ */
2140
+ get calendarMonth() {
2141
+ return this._localeHelperService.localeMonthsAbbreviated[this._dateNavigationService.displayedCalendar.month];
2142
+ }
2143
+ /**
2144
+ * Returns the year value of the calendar.
2145
+ */
2146
+ get calendarYear() {
2147
+ return this._dateNavigationService.displayedCalendar.year;
2148
+ }
2149
+ /**
2150
+ * Calls the ViewManagerService to change to the monthpicker view.
2151
+ */
2152
+ changeToMonthView() {
2153
+ this._viewManagerService.changeToMonthView();
2154
+ }
2155
+ /**
2156
+ * Calls the ViewManagerService to change to the yearpicker view.
2157
+ */
2158
+ changeToYearView() {
2159
+ this._viewManagerService.changeToYearView();
2160
+ }
2161
+ /**
2162
+ * Calls the DateNavigationService to move to the next month.
2163
+ */
2164
+ nextMonth() {
2165
+ this._dateNavigationService.moveToNextMonth();
2166
+ }
2167
+ /**
2168
+ * Calls the DateNavigationService to move to the previous month.
2169
+ */
2170
+ previousMonth() {
2171
+ this._dateNavigationService.moveToPreviousMonth();
2172
+ }
2173
+ /**
2174
+ * Calls the DateNavigationService to move to the current month.
2175
+ */
2176
+ currentMonth() {
2177
+ this._dateNavigationService.moveToCurrentMonth();
2178
+ }
2179
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDaypicker, deps: [{ token: ViewManagerService }, { token: DateNavigationService }, { token: LocaleHelperService }, { token: i4.ClrCommonStringsService }], target: i0.ɵɵFactoryTarget.Component }); }
2180
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrDaypicker, isStandalone: false, selector: "clr-daypicker", host: { attributes: { "role": "application" }, properties: { "class.daypicker": "true" } }, ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n<div class=\"calendar-header\">\n <div class=\"calendar-pickers\">\n <button\n class=\"calendar-btn monthpicker-trigger\"\n type=\"button\"\n (click)=\"changeToMonthView()\"\n [attr.aria-label]=\"monthAttrString\"\n [attr.title]=\"monthAttrString\"\n >\n {{calendarMonth}}\n </button>\n <button\n class=\"calendar-btn yearpicker-trigger\"\n type=\"button\"\n (click)=\"changeToYearView()\"\n [attr.aria-label]=\"yearAttrString\"\n [attr.title]=\"yearAttrString\"\n >\n {{calendarYear}}\n </button>\n </div>\n <div class=\"calendar-switchers\">\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"previousMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerPreviousMonth\"\n >\n <cds-icon shape=\"angle\" direction=\"left\" [attr.title]=\"commonStrings.keys.datepickerPreviousMonth\"></cds-icon>\n </button>\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"currentMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerCurrentMonth\"\n >\n <cds-icon shape=\"event\" [attr.title]=\"commonStrings.keys.datepickerCurrentMonth\"></cds-icon>\n </button>\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"nextMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerNextMonth\"\n >\n <cds-icon shape=\"angle\" direction=\"right\" [attr.title]=\"commonStrings.keys.datepickerNextMonth\"></cds-icon>\n </button>\n </div>\n</div>\n<clr-calendar></clr-calendar>\n<div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n", dependencies: [{ kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "component", type: ClrCalendar, selector: "clr-calendar" }] }); }
2181
+ }
2182
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDaypicker, decorators: [{
2183
+ type: Component,
2184
+ args: [{ selector: 'clr-daypicker', host: { '[class.daypicker]': 'true', role: 'application' }, standalone: false, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n<div class=\"clr-sr-only\">{{commonStrings.keys.modalContentStart}}</div>\n<div class=\"calendar-header\">\n <div class=\"calendar-pickers\">\n <button\n class=\"calendar-btn monthpicker-trigger\"\n type=\"button\"\n (click)=\"changeToMonthView()\"\n [attr.aria-label]=\"monthAttrString\"\n [attr.title]=\"monthAttrString\"\n >\n {{calendarMonth}}\n </button>\n <button\n class=\"calendar-btn yearpicker-trigger\"\n type=\"button\"\n (click)=\"changeToYearView()\"\n [attr.aria-label]=\"yearAttrString\"\n [attr.title]=\"yearAttrString\"\n >\n {{calendarYear}}\n </button>\n </div>\n <div class=\"calendar-switchers\">\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"previousMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerPreviousMonth\"\n >\n <cds-icon shape=\"angle\" direction=\"left\" [attr.title]=\"commonStrings.keys.datepickerPreviousMonth\"></cds-icon>\n </button>\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"currentMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerCurrentMonth\"\n >\n <cds-icon shape=\"event\" [attr.title]=\"commonStrings.keys.datepickerCurrentMonth\"></cds-icon>\n </button>\n <button\n class=\"calendar-btn switcher\"\n type=\"button\"\n (click)=\"nextMonth()\"\n [attr.aria-label]=\"commonStrings.keys.datepickerNextMonth\"\n >\n <cds-icon shape=\"angle\" direction=\"right\" [attr.title]=\"commonStrings.keys.datepickerNextMonth\"></cds-icon>\n </button>\n </div>\n</div>\n<clr-calendar></clr-calendar>\n<div class=\"clr-sr-only\">{{commonStrings.keys.modalContentEnd}}</div>\n" }]
2185
+ }], ctorParameters: () => [{ type: ViewManagerService }, { type: DateNavigationService }, { type: LocaleHelperService }, { type: i4.ClrCommonStringsService }] });
2186
+
2187
+ /*
2188
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2189
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2190
+ * This software is released under MIT license.
2191
+ * The full license information can be found in LICENSE in the root directory of this project.
2192
+ */
2193
+ class ClrDatepickerActions {
2194
+ constructor(commonStrings, popoverService, dateNavigationService, dateFormControlService) {
2195
+ this.commonStrings = commonStrings;
2196
+ this.popoverService = popoverService;
2197
+ this.dateNavigationService = dateNavigationService;
2198
+ this.dateFormControlService = dateFormControlService;
2199
+ }
2200
+ apply() {
2201
+ if (this.dateNavigationService.isRangePicker &&
2202
+ this.dateNavigationService.selectedDay &&
2203
+ this.dateNavigationService.selectedEndDay) {
2204
+ this.dateNavigationService.notifySelectedDayChanged({
2205
+ startDate: this.dateNavigationService.selectedDay,
2206
+ endDate: this.dateNavigationService.selectedEndDay,
2207
+ });
2208
+ this.dateFormControlService.markAsDirty();
2209
+ }
2210
+ else if (!this.dateNavigationService.isRangePicker && this.dateNavigationService.selectedDay) {
2211
+ this.dateNavigationService.notifySelectedDayChanged(this.dateNavigationService.selectedDay);
2212
+ this.dateFormControlService.markAsDirty();
2213
+ }
2214
+ this.popoverService.open = false;
2215
+ }
2216
+ cancel() {
2217
+ this.dateNavigationService.resetSelectedDay();
2218
+ this.popoverService.open = false;
2219
+ }
2220
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerActions, deps: [{ token: i4.ClrCommonStringsService }, { token: i1.ClrPopoverService }, { token: DateNavigationService }, { token: DateFormControlService }], target: i0.ɵɵFactoryTarget.Component }); }
2221
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "21.1.3", type: ClrDatepickerActions, isStandalone: false, selector: "clr-datepicker-actions", host: { properties: { "class.datepicker-actions": "true" } }, ngImport: i0, template: `
2222
+ <button class="btn btn-outline" (click)="cancel()">{{ commonStrings.keys.cancel }}</button>
2223
+ <button class="btn btn-primary" (click)="apply()">{{ commonStrings.keys.apply }}</button>
2224
+ `, isInline: true }); }
2225
+ }
2226
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerActions, decorators: [{
2227
+ type: Component,
2228
+ args: [{
2229
+ selector: 'clr-datepicker-actions',
2230
+ template: `
2231
+ <button class="btn btn-outline" (click)="cancel()">{{ commonStrings.keys.cancel }}</button>
2232
+ <button class="btn btn-primary" (click)="apply()">{{ commonStrings.keys.apply }}</button>
2233
+ `,
2234
+ host: {
2235
+ '[class.datepicker-actions]': 'true',
2236
+ },
2237
+ standalone: false,
2238
+ }]
2239
+ }], ctorParameters: () => [{ type: i4.ClrCommonStringsService }, { type: i1.ClrPopoverService }, { type: DateNavigationService }, { type: DateFormControlService }] });
2240
+
2241
+ /*
2242
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2243
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2244
+ * This software is released under MIT license.
2245
+ * The full license information can be found in LICENSE in the root directory of this project.
2246
+ */
2247
+ class ClrDatepickerViewManager {
2248
+ constructor(commonStrings, viewManagerService, dateNavigationService, dateIOService) {
2249
+ this.commonStrings = commonStrings;
2250
+ this.viewManagerService = viewManagerService;
2251
+ this.dateNavigationService = dateNavigationService;
2252
+ this.dateIOService = dateIOService;
2253
+ }
2254
+ /**
2255
+ * Returns if the current view is the monthpicker.
2256
+ */
2257
+ get isMonthView() {
2258
+ return this.viewManagerService.isMonthView;
2259
+ }
2260
+ /**
2261
+ * Returns if the current view is the yearpicker.
2262
+ */
2263
+ get isYearView() {
2264
+ return this.viewManagerService.isYearView;
2265
+ }
2266
+ /**
2267
+ * Returns if the current view is the daypicker.
2268
+ */
2269
+ get isDayView() {
2270
+ return this.viewManagerService.isDayView;
2271
+ }
2272
+ get hasRangeOptions() {
2273
+ return !!this.dateNavigationService?.isRangePicker && !!this.dateRangeOptions?.length;
2274
+ }
2275
+ get hasActionButtons() {
2276
+ return this.dateNavigationService.hasActionButtons;
2277
+ }
2278
+ get dateRangeOptions() {
2279
+ return this.dateIOService.getRangeOptions();
2280
+ }
2281
+ onRangeOptionSelect(selectedRange) {
2282
+ const startDate = this.dateNavigationService.convertDateToDayModel(selectedRange?.value[0]), endDate = this.dateNavigationService.convertDateToDayModel(selectedRange?.value[1]);
2283
+ this.dateNavigationService.notifySelectedDayChanged({ startDate, endDate }, { emitEvent: !this.hasActionButtons });
2284
+ this.dateNavigationService.moveToSpecificMonth(startDate);
2285
+ }
2286
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerViewManager, deps: [{ token: i4.ClrCommonStringsService }, { token: ViewManagerService }, { token: DateNavigationService }, { token: DateIOService }], target: i0.ɵɵFactoryTarget.Component }); }
2287
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrDatepickerViewManager, isStandalone: false, selector: "clr-datepicker-view-manager", host: { attributes: { "role": "dialog" }, properties: { "class.datepicker": "true", "class.has-range-option": "hasRangeOptions", "class.has-action-buttons": "hasActionButtons", "attr.aria-modal": "true", "attr.aria-label": "commonStrings.keys.datepickerDialogLabel" } }, providers: [DatepickerFocusService], ngImport: i0, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n@if (hasRangeOptions) {\n<clr-vertical-nav class=\"clr-date-range-picker-nav\">\n @for (option of dateRangeOptions; track option) {\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n }\n</clr-vertical-nav>\n<ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n} @else {\n<div class=\"datepicker-view-manager\">\n @if (isMonthView) {\n <clr-monthpicker></clr-monthpicker>\n } @if (isYearView) {\n <clr-yearpicker></clr-yearpicker>\n } @if (isDayView) {\n <clr-daypicker></clr-daypicker>\n } @if (hasActionButtons) {\n <clr-datepicker-actions></clr-datepicker-actions>\n }\n</div>\n}\n\n<ng-template #calendarView>\n <div class=\"datepicker-view-manager\">\n @if (isMonthView) {\n <clr-monthpicker></clr-monthpicker>\n } @if (isYearView) {\n <clr-yearpicker></clr-yearpicker>\n } @if (isDayView) {\n <clr-daypicker></clr-daypicker>\n } @if (hasActionButtons) {\n <clr-datepicker-actions></clr-datepicker-actions>\n }\n </div>\n</ng-template>\n", dependencies: [{ kind: "directive", type: i5$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i6.ClrVerticalNav, selector: "clr-vertical-nav", inputs: ["clrVerticalNavToggleLabel", "clrVerticalNavCollapsible", "clrVerticalNavCollapsed"], outputs: ["clrVerticalNavCollapsedChange"] }, { kind: "component", type: i6.ClrVerticalNavLink, selector: "[clrVerticalNavLink]" }, { kind: "component", type: ClrMonthpicker, selector: "clr-monthpicker" }, { kind: "component", type: ClrYearpicker, selector: "clr-yearpicker" }, { kind: "component", type: ClrDaypicker, selector: "clr-daypicker" }, { kind: "component", type: ClrDatepickerActions, selector: "clr-datepicker-actions" }] }); }
2288
+ }
2289
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerViewManager, decorators: [{
2290
+ type: Component,
2291
+ args: [{ selector: 'clr-datepicker-view-manager', providers: [DatepickerFocusService], host: {
2292
+ '[class.datepicker]': 'true',
2293
+ '[class.has-range-option]': 'hasRangeOptions',
2294
+ '[class.has-action-buttons]': 'hasActionButtons',
2295
+ '[attr.aria-modal]': 'true',
2296
+ '[attr.aria-label]': 'commonStrings.keys.datepickerDialogLabel',
2297
+ role: 'dialog',
2298
+ }, standalone: false, template: "<!--\n ~ Copyright (c) 2016-2026 Broadcom. All Rights Reserved.\n ~ The term \"Broadcom\" refers to Broadcom Inc. and/or its subsidiaries.\n ~ This software is released under MIT license.\n ~ The full license information can be found in LICENSE in the root directory of this project.\n -->\n\n@if (hasRangeOptions) {\n<clr-vertical-nav class=\"clr-date-range-picker-nav\">\n @for (option of dateRangeOptions; track option) {\n <a\n clrVerticalNavLink\n href=\"javascript:void(0)\"\n [attr.aria-label]=\"option?.label\"\n tabindex=\"0\"\n (keyup.enter)=\"onRangeOptionSelect(option)\"\n (click)=\"onRangeOptionSelect(option)\"\n >\n {{option.label}}\n </a>\n }\n</clr-vertical-nav>\n<ng-container *ngTemplateOutlet=\"calendarView\"></ng-container>\n} @else {\n<div class=\"datepicker-view-manager\">\n @if (isMonthView) {\n <clr-monthpicker></clr-monthpicker>\n } @if (isYearView) {\n <clr-yearpicker></clr-yearpicker>\n } @if (isDayView) {\n <clr-daypicker></clr-daypicker>\n } @if (hasActionButtons) {\n <clr-datepicker-actions></clr-datepicker-actions>\n }\n</div>\n}\n\n<ng-template #calendarView>\n <div class=\"datepicker-view-manager\">\n @if (isMonthView) {\n <clr-monthpicker></clr-monthpicker>\n } @if (isYearView) {\n <clr-yearpicker></clr-yearpicker>\n } @if (isDayView) {\n <clr-daypicker></clr-daypicker>\n } @if (hasActionButtons) {\n <clr-datepicker-actions></clr-datepicker-actions>\n }\n </div>\n</ng-template>\n" }]
2299
+ }], ctorParameters: () => [{ type: i4.ClrCommonStringsService }, { type: ViewManagerService }, { type: DateNavigationService }, { type: DateIOService }] });
2300
+
2301
+ /*
2302
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2303
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2304
+ * This software is released under MIT license.
2305
+ * The full license information can be found in LICENSE in the root directory of this project.
2306
+ */
2307
+ class ClrDateContainer extends ClrAbstractContainer {
2308
+ constructor(renderer, elem, popoverService, dateNavigationService, datepickerEnabledService, dateFormControlService, dateIOService, commonStrings, focusService, viewManagerService, controlClassService, layoutService, ngControlService, localeHelperService) {
2309
+ super(layoutService, controlClassService, ngControlService);
2310
+ this.renderer = renderer;
2311
+ this.elem = elem;
2312
+ this.popoverService = popoverService;
2313
+ this.dateNavigationService = dateNavigationService;
2314
+ this.datepickerEnabledService = datepickerEnabledService;
2315
+ this.dateFormControlService = dateFormControlService;
2316
+ this.dateIOService = dateIOService;
2317
+ this.commonStrings = commonStrings;
2318
+ this.viewManagerService = viewManagerService;
2319
+ this.controlClassService = controlClassService;
2320
+ this.layoutService = layoutService;
2321
+ this.ngControlService = ngControlService;
2322
+ this.localeHelperService = localeHelperService;
2323
+ this.focus = false;
2324
+ this.popoverType = ClrPopoverType.DROPDOWN;
2325
+ this.subscriptions.push(focusService.focusChange.subscribe(state => {
2326
+ this.focus = state;
2327
+ }));
2328
+ this.subscriptions.push(popoverService.openChange.subscribe(() => {
2329
+ dateFormControlService.markAsTouched();
2330
+ }));
2331
+ if (dateNavigationService) {
2332
+ const tagName = elem.nativeElement.tagName.toLowerCase();
2333
+ dateNavigationService.hasActionButtons = dateNavigationService.isRangePicker =
2334
+ tagName === 'clr-date-range-container';
2335
+ }
2336
+ }
2337
+ /**
2338
+ * Overrides the locale-derived first day of the week for the calendar.
2339
+ * Accepts a `ClrWeekday` value (Sunday=0 through Saturday=6).
2340
+ * When not set, the first day of the week is determined by the Angular locale.
2341
+ */
2342
+ set firstDayOfWeek(value) {
2343
+ this.localeHelperService.updateFirstDayOfWeek(value ?? null);
2344
+ }
2345
+ /**
2346
+ * For date range picker actions buttons are shown by default
2347
+ */
2348
+ set showActionButtons(flag) {
2349
+ if (this.dateNavigationService.isRangePicker && !flag) {
2350
+ console.error('Error! The date range picker requires action buttons, [showActionButtons] cannot be turned off.');
2351
+ }
2352
+ else {
2353
+ this.dateNavigationService.hasActionButtons = flag;
2354
+ }
2355
+ }
2356
+ set clrPosition(position) {
2357
+ if (!position) {
2358
+ return;
2359
+ }
2360
+ const posIndex = DROPDOWN_POSITIONS.indexOf(position);
2361
+ if (posIndex === -1) {
2362
+ return;
2363
+ }
2364
+ this.viewManagerService.position = DROPDOWN_POSITIONS[posIndex];
2365
+ }
2366
+ set rangeOptions(rangeOptions) {
2367
+ this.dateIOService.setRangeOptions(rangeOptions);
2368
+ }
2369
+ set min(dateString) {
2370
+ if (this.dateNavigationService.isRangePicker) {
2371
+ this.dateIOService.setMinDate(dateString);
2372
+ }
2373
+ else {
2374
+ console.error('Error! The date container [min] input only works for date range pickers. Use the native `min` attribute/property for single-date inputs.');
2375
+ }
2376
+ }
2377
+ set max(dateString) {
2378
+ if (this.dateNavigationService.isRangePicker) {
2379
+ this.dateIOService.setMaxDate(dateString);
2380
+ }
2381
+ else {
2382
+ console.error('Error! The date container [max] input only works for date range pickers. Use the native `max` attribute/property for single-date inputs.');
2383
+ }
2384
+ }
2385
+ set actionButton(button) {
2386
+ this.toggleButton = button;
2387
+ }
2388
+ get popoverPosition() {
2389
+ return this.viewManagerService.position;
2390
+ }
2391
+ get open() {
2392
+ return this.popoverService.open;
2393
+ }
2394
+ /**
2395
+ * Returns if the Datepicker is enabled or not. If disabled, hides the datepicker trigger.
2396
+ */
2397
+ get isEnabled() {
2398
+ return this.datepickerEnabledService.isEnabled;
2399
+ }
2400
+ /**
2401
+ * Return if Datepicker is diabled or not as Form Control
2402
+ */
2403
+ get isInputDateDisabled() {
2404
+ /* clrForm wrapper or without clrForm */
2405
+ return ((this.control && this.control.disabled) || (this.dateFormControlService && this.dateFormControlService.disabled));
2406
+ }
2407
+ get isRangePicker() {
2408
+ return this.dateNavigationService.isRangePicker;
2409
+ }
2410
+ ngAfterViewInit() {
2411
+ this.dateRangeStructuralChecks();
2412
+ this.subscriptions.push(this.popoverService.openChange.subscribe(open => {
2413
+ if (open) {
2414
+ this.initializeCalendar();
2415
+ }
2416
+ else {
2417
+ this.toggleButton.nativeElement.focus();
2418
+ this.dateNavigationService.resetSelectedDay();
2419
+ }
2420
+ }));
2421
+ this.subscriptions.push(this.listenForDateChanges());
2422
+ }
2423
+ /**
2424
+ * Return the label for the toggle button.
2425
+ * If there's a selected date, the date is included in the label.
2426
+ */
2427
+ getToggleButtonLabel(day) {
2428
+ if (day) {
2429
+ const formattedDate = this.dateIOService.toLocaleDisplayFormatString(day.toDate());
2430
+ return this.commonStrings.parse(this.commonStrings.keys.datepickerToggleChangeDateLabel, {
2431
+ SELECTED_DATE: formattedDate,
2432
+ });
2433
+ }
2434
+ return this.commonStrings.keys.datepickerToggleChooseDateLabel;
2435
+ }
2436
+ listenForDateChanges() {
2437
+ // because date-input.ts initializes the input in ngAfterViewInit,
2438
+ // using a databound attribute to change the button labels results in ExpressionChangedAfterItHasBeenCheckedError.
2439
+ // so instead, update the attribute directly on the element
2440
+ return this.dateNavigationService.selectedDayChange
2441
+ .pipe(startWith(this.dateNavigationService.selectedDay))
2442
+ .subscribe(day => {
2443
+ if (this.isEnabled) {
2444
+ const label = this.getToggleButtonLabel(day);
2445
+ const toggleEl = this.toggleButton.nativeElement;
2446
+ this.renderer.setAttribute(toggleEl, 'aria-label', label);
2447
+ this.renderer.setAttribute(toggleEl, 'title', label);
2448
+ }
2449
+ });
2450
+ }
2451
+ /**
2452
+ * Processes the user input and Initializes the Calendar everytime the datepicker popover is open.
2453
+ */
2454
+ initializeCalendar() {
2455
+ this.dateNavigationService.initializeCalendar();
2456
+ }
2457
+ dateRangeStructuralChecks() {
2458
+ if (this.dateNavigationService.isRangePicker) {
2459
+ const inputs = Array.from(this.elem.nativeElement.querySelectorAll('input'));
2460
+ if (inputs.some(input => input.classList.contains('clr-date-input'))) {
2461
+ console.error('Error! clr-date-range-container must contain clrStartDate and clrEndDate inputs');
2462
+ }
2463
+ if (!inputs.some(input => input.classList.contains('clr-date-start-input'))) {
2464
+ console.error('Error! clr-date-range-container must contain clrStartDate input');
2465
+ }
2466
+ if (!inputs.some(input => input.classList.contains('clr-date-end-input'))) {
2467
+ console.error('Error! clr-date-range-container must contain clrEndDate input');
2468
+ }
2469
+ }
2470
+ }
2471
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateContainer, deps: [{ token: i0.Renderer2 }, { token: i0.ElementRef }, { token: i1.ClrPopoverService }, { token: DateNavigationService }, { token: DatepickerEnabledService }, { token: DateFormControlService }, { token: DateIOService }, { token: i4.ClrCommonStringsService }, { token: i7.FormsFocusService }, { token: ViewManagerService }, { token: i7.ControlClassService }, { token: i7.LayoutService, optional: true }, { token: i7.NgControlService }, { token: LocaleHelperService }], target: i0.ɵɵFactoryTarget.Component }); }
2472
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.3", type: ClrDateContainer, isStandalone: false, selector: "clr-date-container, clr-date-range-container", inputs: { firstDayOfWeek: ["clrFirstDayOfWeek", "firstDayOfWeek"], showActionButtons: "showActionButtons", clrPosition: "clrPosition", rangeOptions: "rangeOptions", min: "min", max: "max" }, host: { properties: { "class.clr-date-container": "true", "class.clr-form-control-disabled": "isInputDateDisabled", "class.clr-form-control": "true", "class.clr-row": "addGrid()" } }, providers: [
2473
+ ControlIdService,
2474
+ LocaleHelperService,
2475
+ ControlClassService,
2476
+ FormsFocusService,
2477
+ NgControlService,
2478
+ DateIOService,
2479
+ DateNavigationService,
2480
+ DatepickerEnabledService,
2481
+ DateFormControlService,
2482
+ ViewManagerService,
2483
+ ], viewQueries: [{ propertyName: "actionButton", first: true, predicate: ["actionButton"], descendants: true }], usesInheritance: true, hostDirectives: [{ directive: i1.ClrPopoverHostDirective }], ngImport: i0, template: `
2484
+ <ng-content select="label"></ng-content>
2485
+ @if (!label && addGrid()) {
2486
+ <label></label>
2487
+ }
2488
+ <div class="clr-control-container" [ngClass]="controlClass()">
2489
+ <div class="clr-input-wrapper" clrPopoverOrigin>
2490
+ <div class="clr-input-group" [class.clr-focus]="focus">
2491
+ <!-- render range inputs only if using clr-date-range-container -->
2492
+ @if (isRangePicker) {
2493
+ <ng-content select="[clrStartDate]"></ng-content>
2494
+ <span class="date-range-separator">-</span>
2495
+ <ng-content select="[clrEndDate]"></ng-content>
2496
+ }
2497
+ <!-- no @if for the singe-date input because it breaks the "auto-wrapped" date picker -->
2498
+ <ng-content select="[clrDate]"></ng-content>
2499
+ @if (isEnabled) {
2500
+ <button
2501
+ #actionButton
2502
+ type="button"
2503
+ clrPopoverOpenCloseButton
2504
+ class="clr-input-group-icon-action"
2505
+ [disabled]="isInputDateDisabled"
2506
+ >
2507
+ <cds-icon status="info" shape="calendar"></cds-icon>
2508
+ </button>
2509
+ }
2510
+ <clr-datepicker-view-manager
2511
+ *clrPopoverContent="
2512
+ open;
2513
+ at: popoverPosition;
2514
+ type: popoverType;
2515
+ outsideClickToClose: true;
2516
+ scrollToClose: true
2517
+ "
2518
+ cdkTrapFocus
2519
+ ></clr-datepicker-view-manager>
2520
+ </div>
2521
+ </div>
2522
+ @if (showHelper) {
2523
+ <ng-content select="clr-control-helper"></ng-content>
2524
+ }
2525
+ @if (showInvalid) {
2526
+ <ng-content select="clr-control-error"></ng-content>
2527
+ }
2528
+ @if (showValid) {
2529
+ <ng-content select="clr-control-success"></ng-content>
2530
+ }
2531
+ </div>
2532
+ `, isInline: true, dependencies: [{ kind: "directive", type: i5$1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i4.CdkTrapFocusModule_CdkTrapFocus, selector: "[cdkTrapFocus]" }, { kind: "directive", type: i1.ClrPopoverOrigin, selector: "[clrPopoverOrigin]" }, { kind: "directive", type: i1.ClrPopoverOpenCloseButton, selector: "[clrPopoverOpenCloseButton]", outputs: ["clrPopoverOpenCloseChange"] }, { kind: "directive", type: i1.ClrPopoverContent, selector: "[clrPopoverContent]", inputs: ["clrPopoverContent", "clrPopoverContentAt", "clrPopoverContentAvailablePositions", "clrPopoverContentType", "clrPopoverContentOutsideClickToClose", "clrPopoverContentScrollToClose", "clrPopoverContentOrigin"] }, { kind: "component", type: i5.ClrIcon, selector: "clr-icon, cds-icon", inputs: ["shape", "size", "direction", "flip", "solid", "status", "inverse", "badge"] }, { kind: "directive", type: i7.ClrControlLabel, selector: "label", inputs: ["id", "for"] }, { kind: "component", type: ClrDatepickerViewManager, selector: "clr-datepicker-view-manager" }] }); }
2533
+ }
2534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateContainer, decorators: [{
2535
+ type: Component,
2536
+ args: [{
2537
+ selector: 'clr-date-container, clr-date-range-container',
2538
+ template: `
2539
+ <ng-content select="label"></ng-content>
2540
+ @if (!label && addGrid()) {
2541
+ <label></label>
2542
+ }
2543
+ <div class="clr-control-container" [ngClass]="controlClass()">
2544
+ <div class="clr-input-wrapper" clrPopoverOrigin>
2545
+ <div class="clr-input-group" [class.clr-focus]="focus">
2546
+ <!-- render range inputs only if using clr-date-range-container -->
2547
+ @if (isRangePicker) {
2548
+ <ng-content select="[clrStartDate]"></ng-content>
2549
+ <span class="date-range-separator">-</span>
2550
+ <ng-content select="[clrEndDate]"></ng-content>
2551
+ }
2552
+ <!-- no @if for the singe-date input because it breaks the "auto-wrapped" date picker -->
2553
+ <ng-content select="[clrDate]"></ng-content>
2554
+ @if (isEnabled) {
2555
+ <button
2556
+ #actionButton
2557
+ type="button"
2558
+ clrPopoverOpenCloseButton
2559
+ class="clr-input-group-icon-action"
2560
+ [disabled]="isInputDateDisabled"
2561
+ >
2562
+ <cds-icon status="info" shape="calendar"></cds-icon>
2563
+ </button>
2564
+ }
2565
+ <clr-datepicker-view-manager
2566
+ *clrPopoverContent="
2567
+ open;
2568
+ at: popoverPosition;
2569
+ type: popoverType;
2570
+ outsideClickToClose: true;
2571
+ scrollToClose: true
2572
+ "
2573
+ cdkTrapFocus
2574
+ ></clr-datepicker-view-manager>
2575
+ </div>
2576
+ </div>
2577
+ @if (showHelper) {
2578
+ <ng-content select="clr-control-helper"></ng-content>
2579
+ }
2580
+ @if (showInvalid) {
2581
+ <ng-content select="clr-control-error"></ng-content>
2582
+ }
2583
+ @if (showValid) {
2584
+ <ng-content select="clr-control-success"></ng-content>
2585
+ }
2586
+ </div>
2587
+ `,
2588
+ providers: [
2589
+ ControlIdService,
2590
+ LocaleHelperService,
2591
+ ControlClassService,
2592
+ FormsFocusService,
2593
+ NgControlService,
2594
+ DateIOService,
2595
+ DateNavigationService,
2596
+ DatepickerEnabledService,
2597
+ DateFormControlService,
2598
+ ViewManagerService,
2599
+ ],
2600
+ hostDirectives: [ClrPopoverHostDirective],
2601
+ host: {
2602
+ '[class.clr-date-container]': 'true',
2603
+ '[class.clr-form-control-disabled]': 'isInputDateDisabled',
2604
+ '[class.clr-form-control]': 'true',
2605
+ '[class.clr-row]': 'addGrid()',
2606
+ },
2607
+ standalone: false,
2608
+ }]
2609
+ }], ctorParameters: () => [{ type: i0.Renderer2 }, { type: i0.ElementRef }, { type: i1.ClrPopoverService }, { type: DateNavigationService }, { type: DatepickerEnabledService }, { type: DateFormControlService }, { type: DateIOService }, { type: i4.ClrCommonStringsService }, { type: i7.FormsFocusService }, { type: ViewManagerService }, { type: i7.ControlClassService }, { type: i7.LayoutService, decorators: [{
2610
+ type: Optional
2611
+ }] }, { type: i7.NgControlService }, { type: LocaleHelperService }], propDecorators: { firstDayOfWeek: [{
2612
+ type: Input,
2613
+ args: ['clrFirstDayOfWeek']
2614
+ }], showActionButtons: [{
2615
+ type: Input,
2616
+ args: ['showActionButtons']
2617
+ }], clrPosition: [{
2618
+ type: Input,
2619
+ args: ['clrPosition']
2620
+ }], rangeOptions: [{
2621
+ type: Input
2622
+ }], min: [{
2623
+ type: Input
2624
+ }], max: [{
2625
+ type: Input
2626
+ }], actionButton: [{
2627
+ type: ViewChild,
2628
+ args: ['actionButton']
2629
+ }] } });
2630
+
2631
+ /*
2632
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2633
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2634
+ * This software is released under MIT license.
2635
+ * The full license information can be found in LICENSE in the root directory of this project.
2636
+ */
2637
+ // There are four ways the datepicker value is set
2638
+ // 1. Value set by user typing into text input as a string ex: '01/28/2015'
2639
+ // 2. Value set explicitly by Angular Forms APIs as a string ex: '01/28/2015'
2640
+ // 3. Value set by user via datepicker UI as a Date Object
2641
+ // 4. Value set via `clrDate` input as a Date Object
2642
+ class ClrDateInputBase extends WrappedFormControl {
2643
+ constructor(viewContainerRef, injector, el, renderer, control, container, dateIOService, dateNavigationService, datepickerEnabledService, dateFormControlService, platformId, focusService, datepickerFocusService) {
2644
+ super(viewContainerRef, ClrDateContainer, injector, control, renderer, el);
2645
+ this.el = el;
2646
+ this.renderer = renderer;
2647
+ this.control = control;
2648
+ this.container = container;
2649
+ this.dateIOService = dateIOService;
2650
+ this.dateNavigationService = dateNavigationService;
2651
+ this.datepickerEnabledService = datepickerEnabledService;
2652
+ this.dateFormControlService = dateFormControlService;
2653
+ this.platformId = platformId;
2654
+ this.focusService = focusService;
2655
+ this.datepickerFocusService = datepickerFocusService;
2656
+ this.index = 1;
2657
+ }
2658
+ get disabled() {
2659
+ if (this.dateFormControlService) {
2660
+ return this.dateFormControlService.disabled || !!this.control?.control?.disabled;
2661
+ }
2662
+ return null;
2663
+ }
2664
+ set disabled(value) {
2665
+ if (this.dateFormControlService) {
2666
+ this.dateFormControlService.setDisabled(isBooleanAttributeSet(value));
2667
+ }
2668
+ }
2669
+ get placeholderText() {
2670
+ return this.placeholder ? this.placeholder : this.dateIOService.placeholderText;
2671
+ }
2672
+ get inputType() {
2673
+ return isPlatformBrowser(this.platformId) && this.usingNativeDatepicker() ? 'date' : 'text';
2674
+ }
2675
+ ngOnInit() {
2676
+ super.ngOnInit();
2677
+ this.populateServicesFromContainerComponent();
2678
+ this.subscriptions.push(this.listenForUserSelectedDayChanges(), this.listenForControlValueChanges(), this.listenForTouchChanges(), this.listenForDirtyChanges(), this.listenForInputRefocus());
2679
+ }
2680
+ ngAfterViewInit() {
2681
+ // I don't know why I have to do this but after using the new HostWrapping Module I have to delay the processing
2682
+ // of the initial Input set by the user to here. If I do not 2 issues occur:
2683
+ // 1. The Input setter is called before ngOnInit. ngOnInit initializes the services without which the setter fails.
2684
+ // 2. The Renderer doesn't work before ngAfterViewInit (It used to before the new HostWrapping Module for some reason).
2685
+ // I need the renderer to set the value property on the input to make sure that if the user has supplied a Date
2686
+ // input object, we reflect it with the right date on the input field using the IO service. I am not sure if
2687
+ // these are major issues or not but just noting them down here.
2688
+ this.processInitialInputs();
2689
+ }
2690
+ setFocusStates() {
2691
+ this.setFocus(true);
2692
+ }
2693
+ triggerValidation() {
2694
+ super.triggerValidation();
2695
+ this.setFocus(false);
2696
+ }
2697
+ onValueChange(target) {
2698
+ const validDateValue = this.dateIOService.getDateValueFromDateString(target.value);
2699
+ if (this.usingClarityDatepicker() && validDateValue) {
2700
+ this.updateDate(validDateValue, true);
2701
+ }
2702
+ else if (this.usingNativeDatepicker()) {
2703
+ const [year, month, day] = target.value.split('-');
2704
+ this.updateDate(new Date(+year, +month - 1, +day), true);
2705
+ }
2706
+ else {
2707
+ this.emitDateOutput(null);
2708
+ }
2709
+ }
2710
+ datepickerHasFormControl() {
2711
+ return !!this.control;
2712
+ }
2713
+ setDate(date) {
2714
+ if (typeof date === 'string') {
2715
+ date = new Date(date);
2716
+ }
2717
+ if (this.previousDateChange !== date) {
2718
+ this.updateDate(date);
2719
+ }
2720
+ if (!this.initialClrDateInputValue) {
2721
+ this.initialClrDateInputValue = date;
2722
+ }
2723
+ }
2724
+ triggerControlInputValidation() {
2725
+ if (this.datepickerHasFormControl()) {
2726
+ this.control.control?.updateValueAndValidity({ emitEvent: false });
2727
+ this.control.control?.setErrors(this.control.control.errors);
2728
+ }
2729
+ }
2730
+ usingClarityDatepicker() {
2731
+ return this.datepickerEnabledService.isEnabled;
2732
+ }
2733
+ usingNativeDatepicker() {
2734
+ return !this.datepickerEnabledService.isEnabled;
2735
+ }
2736
+ setFocus(focus) {
2737
+ if (this.focusService) {
2738
+ this.focusService.focused = focus;
2739
+ }
2740
+ }
2741
+ populateServicesFromContainerComponent() {
2742
+ if (!this.container) {
2743
+ this.dateIOService = this.getProviderFromContainer(DateIOService);
2744
+ this.dateNavigationService = this.getProviderFromContainer(DateNavigationService);
2745
+ this.datepickerEnabledService = this.getProviderFromContainer(DatepickerEnabledService);
2746
+ this.dateFormControlService = this.getProviderFromContainer(DateFormControlService);
2747
+ }
2748
+ }
2749
+ processInitialInputs() {
2750
+ if (this.datepickerHasFormControl()) {
2751
+ this.updateDate(this.dateIOService.getDateValueFromDateString(this.control.value));
2752
+ }
2753
+ else {
2754
+ this.updateDate(this.initialClrDateInputValue);
2755
+ }
2756
+ }
2757
+ updateDate(value, setByUserInteraction = false) {
2758
+ const date = this.getValidDateValueFromDate(value);
2759
+ if (setByUserInteraction) {
2760
+ this.emitDateOutput(date);
2761
+ }
2762
+ else {
2763
+ this.previousDateChange = date;
2764
+ }
2765
+ if (this.dateNavigationService) {
2766
+ const dayModel = date ? new DayModel(date.getFullYear(), date.getMonth(), date.getDate()) : null;
2767
+ this.updateDayModel(dayModel);
2768
+ }
2769
+ this.updateInput(date);
2770
+ }
2771
+ updateInput(date) {
2772
+ if (date) {
2773
+ const dateString = this.dateIOService.toLocaleDisplayFormatString(date);
2774
+ if (this.usingNativeDatepicker()) {
2775
+ // valueAsDate expects UTC, date from input is time-zoned
2776
+ date.setMinutes(date.getMinutes() - date.getTimezoneOffset());
2777
+ this.renderer.setProperty(this.el.nativeElement, 'valueAsDate', date);
2778
+ }
2779
+ else if (this.datepickerHasFormControl() && dateString !== this.control.value) {
2780
+ this.control.control.setValue(dateString);
2781
+ }
2782
+ else {
2783
+ this.renderer.setProperty(this.el.nativeElement, 'value', dateString);
2784
+ }
2785
+ this.validateDateRange();
2786
+ }
2787
+ else {
2788
+ this.renderer.setProperty(this.el.nativeElement, 'value', '');
2789
+ }
2790
+ }
2791
+ getValidDateValueFromDate(date) {
2792
+ if (this.dateIOService) {
2793
+ const dateString = this.dateIOService.toLocaleDisplayFormatString(date);
2794
+ return this.dateIOService.getDateValueFromDateString(dateString);
2795
+ }
2796
+ else {
2797
+ return null;
2798
+ }
2799
+ }
2800
+ emitDateOutput(date) {
2801
+ if (!datesAreEqual(date, this.previousDateChange)) {
2802
+ this.dateChange.emit(date);
2803
+ this.previousDateChange = date;
2804
+ }
2805
+ else if (!date && this.previousDateChange) {
2806
+ this.dateChange.emit(null);
2807
+ this.previousDateChange = null;
2808
+ }
2809
+ }
2810
+ listenForControlValueChanges() {
2811
+ if (this.datepickerHasFormControl()) {
2812
+ return this.control.valueChanges
2813
+ .pipe(
2814
+ // only update date value if not being set by user
2815
+ filter(() => !this.datepickerFocusService.elementIsFocused(this.el.nativeElement)))
2816
+ .subscribe((value) => this.updateDate(this.dateIOService.getDateValueFromDateString(value)));
2817
+ }
2818
+ else {
2819
+ return null;
2820
+ }
2821
+ }
2822
+ listenForUserSelectedDayChanges() {
2823
+ return this.userSelectedDayChange.subscribe(dayModel => this.updateDate(dayModel?.toDate(), true));
2824
+ }
2825
+ listenForTouchChanges() {
2826
+ return this.dateFormControlService.touchedChange
2827
+ .pipe(filter(() => this.datepickerHasFormControl()))
2828
+ .subscribe(() => this.control.control.markAsTouched());
2829
+ }
2830
+ listenForDirtyChanges() {
2831
+ return this.dateFormControlService.dirtyChange
2832
+ .pipe(filter(() => this.datepickerHasFormControl()))
2833
+ .subscribe(() => this.control.control.markAsDirty());
2834
+ }
2835
+ listenForInputRefocus() {
2836
+ return this.dateNavigationService.selectedDayChange
2837
+ .pipe(filter(date => !!date && !this.dateNavigationService.isRangePicker))
2838
+ .subscribe(() => this.datepickerFocusService.focusInput(this.el.nativeElement));
2839
+ }
2840
+ /**
2841
+ * In case of date range error, both start & end date field validation has to be triggered
2842
+ * if either of the field gets updated
2843
+ */
2844
+ validateDateRange() {
2845
+ if (this.dateNavigationService.isRangePicker) {
2846
+ const controls = this.ngControlService?.controls;
2847
+ const isValid = this.dateNavigationService.selectedDay?.isBefore(this.dateNavigationService.selectedEndDay, true);
2848
+ if (isValid && controls?.some(control => control.hasError('range'))) {
2849
+ controls.forEach((ngControl) => {
2850
+ ngControl?.control?.updateValueAndValidity({ emitEvent: false });
2851
+ });
2852
+ }
2853
+ }
2854
+ }
2855
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInputBase, deps: [{ token: i0.ViewContainerRef }, { token: i0.Injector }, { token: i0.ElementRef }, { token: i0.Renderer2 }, { token: i1$1.NgControl, optional: true, self: true }, { token: forwardRef(() => ClrDateContainer), optional: true }, { token: DateIOService, optional: true }, { token: DateNavigationService, optional: true }, { token: DatepickerEnabledService, optional: true }, { token: DateFormControlService, optional: true }, { token: PLATFORM_ID }, { token: i7.FormsFocusService, optional: true }, { token: DatepickerFocusService }], target: i0.ɵɵFactoryTarget.Directive }); }
2856
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrDateInputBase, isStandalone: true, inputs: { placeholder: "placeholder", disabled: "disabled" }, host: { listeners: { "focus": "setFocusStates()", "change": "onValueChange($event.target)" }, properties: { "disabled": "this.disabled", "attr.placeholder": "this.placeholderText", "attr.type": "this.inputType" } }, usesInheritance: true, ngImport: i0 }); }
2857
+ }
2858
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInputBase, decorators: [{
2859
+ type: Directive
2860
+ }], ctorParameters: () => [{ type: i0.ViewContainerRef }, { type: i0.Injector }, { type: i0.ElementRef }, { type: i0.Renderer2 }, { type: i1$1.NgControl, decorators: [{
2861
+ type: Self
2862
+ }, {
2863
+ type: Optional
2864
+ }] }, { type: ClrDateContainer, decorators: [{
2865
+ type: Optional
2866
+ }, {
2867
+ type: Inject,
2868
+ args: [forwardRef(() => ClrDateContainer)]
2869
+ }] }, { type: DateIOService, decorators: [{
2870
+ type: Optional
2871
+ }] }, { type: DateNavigationService, decorators: [{
2872
+ type: Optional
2873
+ }] }, { type: DatepickerEnabledService, decorators: [{
2874
+ type: Optional
2875
+ }] }, { type: DateFormControlService, decorators: [{
2876
+ type: Optional
2877
+ }] }, { type: undefined, decorators: [{
2878
+ type: Inject,
2879
+ args: [PLATFORM_ID]
2880
+ }] }, { type: i7.FormsFocusService, decorators: [{
2881
+ type: Optional
2882
+ }] }, { type: DatepickerFocusService }], propDecorators: { placeholder: [{
2883
+ type: Input
2884
+ }], disabled: [{
2885
+ type: Input,
2886
+ args: ['disabled']
2887
+ }, {
2888
+ type: HostBinding,
2889
+ args: ['disabled']
2890
+ }], placeholderText: [{
2891
+ type: HostBinding,
2892
+ args: ['attr.placeholder']
2893
+ }], inputType: [{
2894
+ type: HostBinding,
2895
+ args: ['attr.type']
2896
+ }], setFocusStates: [{
2897
+ type: HostListener,
2898
+ args: ['focus']
2899
+ }], onValueChange: [{
2900
+ type: HostListener,
2901
+ args: ['change', ['$event.target']]
2902
+ }] } });
2903
+
2904
+ /*
2905
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2906
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2907
+ * This software is released under MIT license.
2908
+ * The full license information can be found in LICENSE in the root directory of this project.
2909
+ */
2910
+ class ClrDateInput extends ClrDateInputBase {
2911
+ constructor() {
2912
+ super(...arguments);
2913
+ this.dateChange = new EventEmitter(false);
2914
+ }
2915
+ set date(date) {
2916
+ this.setDate(date);
2917
+ }
2918
+ set min(dateString) {
2919
+ this.dateIOService.setMinDate(dateString);
2920
+ }
2921
+ set max(dateString) {
2922
+ this.dateIOService.setMaxDate(dateString);
2923
+ }
2924
+ get userSelectedDayChange() {
2925
+ return this.dateNavigationService.selectedDayChange;
2926
+ }
2927
+ updateDayModel(dayModel) {
2928
+ this.dateNavigationService.persistedDate = this.dateNavigationService.selectedDay = dayModel;
2929
+ }
2930
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInput, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2931
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrDateInput, isStandalone: false, selector: "[clrDate]", inputs: { date: ["clrDate", "date"], min: "min", max: "max" }, outputs: { dateChange: "clrDateChange" }, host: { properties: { "class.clr-input": "true", "class.clr-date-input": "true" } }, providers: [DatepickerFocusService], usesInheritance: true, ngImport: i0 }); }
2932
+ }
2933
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInput, decorators: [{
2934
+ type: Directive,
2935
+ args: [{
2936
+ selector: '[clrDate]',
2937
+ host: {
2938
+ '[class.clr-input]': 'true',
2939
+ '[class.clr-date-input]': 'true',
2940
+ },
2941
+ providers: [DatepickerFocusService],
2942
+ standalone: false,
2943
+ }]
2944
+ }], propDecorators: { dateChange: [{
2945
+ type: Output,
2946
+ args: ['clrDateChange']
2947
+ }], date: [{
2948
+ type: Input,
2949
+ args: ['clrDate']
2950
+ }], min: [{
2951
+ type: Input
2952
+ }], max: [{
2953
+ type: Input
2954
+ }] } });
2955
+
2956
+ /*
2957
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
2958
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
2959
+ * This software is released under MIT license.
2960
+ * The full license information can be found in LICENSE in the root directory of this project.
2961
+ */
2962
+ class ClrStartDateInput extends ClrDateInputBase {
2963
+ constructor() {
2964
+ super(...arguments);
2965
+ this.dateChange = new EventEmitter(false);
2966
+ this.inputWidth = 13;
2967
+ }
2968
+ set date(date) {
2969
+ this.setDate(date);
2970
+ }
2971
+ get inputSize() {
2972
+ return this.inputWidth;
2973
+ }
2974
+ get userSelectedDayChange() {
2975
+ return this.dateNavigationService.selectedDayChange;
2976
+ }
2977
+ ngOnInit() {
2978
+ super.ngOnInit();
2979
+ this.subscriptions.push(this.dateIOService.minDateChange.subscribe(() => this.triggerControlInputValidation()));
2980
+ }
2981
+ updateDayModel(dayModel) {
2982
+ this.dateNavigationService.persistedDate = this.dateNavigationService.selectedDay = dayModel;
2983
+ }
2984
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStartDateInput, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
2985
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrStartDateInput, isStandalone: false, selector: "[clrStartDate]", inputs: { inputWidth: "inputWidth", date: ["clrStartDate", "date"] }, outputs: { dateChange: "clrStartDateChange" }, host: { properties: { "class.clr-input": "true", "class.clr-date-start-input": "true", "style.text-align": "'right'", "attr.size": "this.inputSize" } }, providers: [DatepickerFocusService], usesInheritance: true, ngImport: i0 }); }
2986
+ }
2987
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStartDateInput, decorators: [{
2988
+ type: Directive,
2989
+ args: [{
2990
+ selector: '[clrStartDate]',
2991
+ host: {
2992
+ '[class.clr-input]': 'true',
2993
+ '[class.clr-date-start-input]': 'true',
2994
+ '[style.text-align]': "'right'",
2995
+ },
2996
+ providers: [DatepickerFocusService],
2997
+ standalone: false,
2998
+ }]
2999
+ }], propDecorators: { dateChange: [{
3000
+ type: Output,
3001
+ args: ['clrStartDateChange']
3002
+ }], inputWidth: [{
3003
+ type: Input,
3004
+ args: ['inputWidth']
3005
+ }], date: [{
3006
+ type: Input,
3007
+ args: ['clrStartDate']
3008
+ }], inputSize: [{
3009
+ type: HostBinding,
3010
+ args: ['attr.size']
3011
+ }] } });
3012
+
3013
+ /*
3014
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
3015
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3016
+ * This software is released under MIT license.
3017
+ * The full license information can be found in LICENSE in the root directory of this project.
3018
+ */
3019
+ class ClrEndDateInput extends ClrDateInputBase {
3020
+ constructor() {
3021
+ super(...arguments);
3022
+ this.dateChange = new EventEmitter(false);
3023
+ this.inputWidth = 13;
3024
+ }
3025
+ set date(date) {
3026
+ this.setDate(date);
3027
+ }
3028
+ get inputSize() {
3029
+ return this.inputWidth;
3030
+ }
3031
+ get userSelectedDayChange() {
3032
+ return this.dateNavigationService.selectedEndDayChange;
3033
+ }
3034
+ ngOnInit() {
3035
+ super.ngOnInit();
3036
+ this.subscriptions.push(this.dateIOService.maxDateChange.subscribe(() => this.triggerControlInputValidation()));
3037
+ }
3038
+ updateDayModel(dayModel) {
3039
+ this.dateNavigationService.persistedEndDate = this.dateNavigationService.selectedEndDay = dayModel;
3040
+ }
3041
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrEndDateInput, deps: null, target: i0.ɵɵFactoryTarget.Directive }); }
3042
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrEndDateInput, isStandalone: false, selector: "[clrEndDate]", inputs: { inputWidth: "inputWidth", date: ["clrEndDate", "date"] }, outputs: { dateChange: "clrEndDateChange" }, host: { properties: { "class.clr-input": "true", "class.clr-date-end-input": "true", "attr.size": "this.inputSize" } }, providers: [DatepickerFocusService], usesInheritance: true, ngImport: i0 }); }
3043
+ }
3044
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrEndDateInput, decorators: [{
3045
+ type: Directive,
3046
+ args: [{
3047
+ selector: '[clrEndDate]',
3048
+ host: {
3049
+ '[class.clr-input]': 'true',
3050
+ '[class.clr-date-end-input]': 'true',
3051
+ },
3052
+ providers: [DatepickerFocusService],
3053
+ standalone: false,
3054
+ }]
3055
+ }], propDecorators: { dateChange: [{
3056
+ type: Output,
3057
+ args: ['clrEndDateChange']
3058
+ }], inputWidth: [{
3059
+ type: Input,
3060
+ args: ['inputWidth']
3061
+ }], date: [{
3062
+ type: Input,
3063
+ args: ['clrEndDate']
3064
+ }], inputSize: [{
3065
+ type: HostBinding,
3066
+ args: ['attr.size']
3067
+ }] } });
3068
+
3069
+ /*
3070
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
3071
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3072
+ * This software is released under MIT license.
3073
+ * The full license information can be found in LICENSE in the root directory of this project.
3074
+ */
3075
+ class ClrDateInputValidator {
3076
+ constructor(dateIOService) {
3077
+ this.dateIOService = dateIOService;
3078
+ }
3079
+ validate(control) {
3080
+ if (this.dateIOService) {
3081
+ const value = this.dateIOService.getDateValueFromDateString(control.value);
3082
+ const minDate = this.dateIOService.disabledDates.minDate.toDate();
3083
+ const maxDate = this.dateIOService.disabledDates.maxDate.toDate();
3084
+ if (value && value < minDate) {
3085
+ return { min: { min: minDate.toLocaleDateString(), actual: value.toLocaleDateString() } };
3086
+ }
3087
+ else if (value && value > maxDate) {
3088
+ return { max: { max: maxDate.toLocaleDateString(), actual: value.toLocaleDateString() } };
3089
+ }
3090
+ }
3091
+ return null;
3092
+ }
3093
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInputValidator, deps: [{ token: DateIOService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
3094
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrDateInputValidator, isStandalone: false, selector: "[clrDate], [clrStartDate], [clrEndDate]", providers: [{ provide: NG_VALIDATORS, useExisting: ClrDateInputValidator, multi: true }], ngImport: i0 }); }
3095
+ }
3096
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDateInputValidator, decorators: [{
3097
+ type: Directive,
3098
+ args: [{
3099
+ selector: '[clrDate], [clrStartDate], [clrEndDate]',
3100
+ providers: [{ provide: NG_VALIDATORS, useExisting: ClrDateInputValidator, multi: true }],
3101
+ standalone: false,
3102
+ }]
3103
+ }], ctorParameters: () => [{ type: DateIOService, decorators: [{
3104
+ type: Optional
3105
+ }] }] });
3106
+ class ClrStartDateInputValidator {
3107
+ constructor(dateIOService, dateNavigationService) {
3108
+ this.dateIOService = dateIOService;
3109
+ this.dateNavigationService = dateNavigationService;
3110
+ }
3111
+ validate(control) {
3112
+ if (this.dateIOService) {
3113
+ const value = this.dateIOService.getDateValueFromDateString(control.value);
3114
+ const endDate = this.dateNavigationService?.selectedEndDay?.toDate();
3115
+ if (value && endDate && value > endDate) {
3116
+ return { range: { startDate: value, endDate } };
3117
+ }
3118
+ }
3119
+ return null;
3120
+ }
3121
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStartDateInputValidator, deps: [{ token: DateIOService, optional: true }, { token: DateNavigationService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
3122
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrStartDateInputValidator, isStandalone: false, selector: "[clrStartDate]", providers: [{ provide: NG_VALIDATORS, useExisting: ClrStartDateInputValidator, multi: true }], ngImport: i0 }); }
3123
+ }
3124
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrStartDateInputValidator, decorators: [{
3125
+ type: Directive,
3126
+ args: [{
3127
+ selector: '[clrStartDate]',
3128
+ providers: [{ provide: NG_VALIDATORS, useExisting: ClrStartDateInputValidator, multi: true }],
3129
+ standalone: false,
3130
+ }]
3131
+ }], ctorParameters: () => [{ type: DateIOService, decorators: [{
3132
+ type: Optional
3133
+ }] }, { type: DateNavigationService, decorators: [{
3134
+ type: Optional
3135
+ }] }] });
3136
+ class ClrEndDateInputValidator {
3137
+ constructor(dateIOService, dateNavigationService) {
3138
+ this.dateIOService = dateIOService;
3139
+ this.dateNavigationService = dateNavigationService;
3140
+ }
3141
+ validate(control) {
3142
+ if (this.dateIOService) {
3143
+ const value = this.dateIOService.getDateValueFromDateString(control.value);
3144
+ const startDate = this.dateNavigationService?.selectedDay?.toDate();
3145
+ if (value && startDate && value < startDate) {
3146
+ return { range: { startDate, endDate: value } };
3147
+ }
3148
+ }
3149
+ return null;
3150
+ }
3151
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrEndDateInputValidator, deps: [{ token: DateIOService, optional: true }, { token: DateNavigationService, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
3152
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.1.3", type: ClrEndDateInputValidator, isStandalone: false, selector: "[clrEndDate]", providers: [{ provide: NG_VALIDATORS, useExisting: ClrEndDateInputValidator, multi: true }], ngImport: i0 }); }
3153
+ }
3154
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrEndDateInputValidator, decorators: [{
3155
+ type: Directive,
3156
+ args: [{
3157
+ selector: '[clrEndDate]',
3158
+ providers: [{ provide: NG_VALIDATORS, useExisting: ClrEndDateInputValidator, multi: true }],
3159
+ standalone: false,
3160
+ }]
3161
+ }], ctorParameters: () => [{ type: DateIOService, decorators: [{
3162
+ type: Optional
3163
+ }] }, { type: DateNavigationService, decorators: [{
3164
+ type: Optional
3165
+ }] }] });
3166
+
3167
+ /*
3168
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
3169
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3170
+ * This software is released under MIT license.
3171
+ * The full license information can be found in LICENSE in the root directory of this project.
3172
+ */
3173
+
3174
+ /*
3175
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
3176
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3177
+ * This software is released under MIT license.
3178
+ * The full license information can be found in LICENSE in the root directory of this project.
3179
+ */
3180
+ const CLR_DATEPICKER_DIRECTIVES = [
3181
+ ClrDateInput,
3182
+ ClrDay,
3183
+ ClrDateContainer,
3184
+ ClrDateInputValidator,
3185
+ ClrStartDateInput,
3186
+ ClrEndDateInput,
3187
+ ClrStartDateInputValidator,
3188
+ ClrEndDateInputValidator,
3189
+ ClrDatepickerViewManager,
3190
+ ClrMonthpicker,
3191
+ ClrYearpicker,
3192
+ ClrDaypicker,
3193
+ ClrCalendar,
3194
+ ClrDatepickerActions,
3195
+ ];
3196
+ class ClrDatepickerModule {
3197
+ constructor() {
3198
+ ClarityIcons.addIcons(successStandardIcon, errorStandardIcon, angleIcon, eventIcon, calendarIcon);
3199
+ }
3200
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
3201
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerModule, declarations: [ClrDateInput,
3202
+ ClrDay,
3203
+ ClrDateContainer,
3204
+ ClrDateInputValidator,
3205
+ ClrStartDateInput,
3206
+ ClrEndDateInput,
3207
+ ClrStartDateInputValidator,
3208
+ ClrEndDateInputValidator,
3209
+ ClrDatepickerViewManager,
3210
+ ClrMonthpicker,
3211
+ ClrYearpicker,
3212
+ ClrDaypicker,
3213
+ ClrCalendar,
3214
+ ClrDatepickerActions], imports: [CommonModule,
3215
+ CdkTrapFocusModule,
3216
+ ClrHostWrappingModule,
3217
+ ClrConditionalModule,
3218
+ ClrPopoverModuleNext,
3219
+ ClrIcon,
3220
+ ClrCommonFormsModule,
3221
+ ClrVerticalNavModule], exports: [ClrDateInput,
3222
+ ClrDay,
3223
+ ClrDateContainer,
3224
+ ClrDateInputValidator,
3225
+ ClrStartDateInput,
3226
+ ClrEndDateInput,
3227
+ ClrStartDateInputValidator,
3228
+ ClrEndDateInputValidator,
3229
+ ClrDatepickerViewManager,
3230
+ ClrMonthpicker,
3231
+ ClrYearpicker,
3232
+ ClrDaypicker,
3233
+ ClrCalendar,
3234
+ ClrDatepickerActions] }); }
3235
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerModule, imports: [CommonModule,
3236
+ CdkTrapFocusModule,
3237
+ ClrHostWrappingModule,
3238
+ ClrConditionalModule,
3239
+ ClrPopoverModuleNext,
3240
+ ClrIcon,
3241
+ ClrCommonFormsModule,
3242
+ ClrVerticalNavModule] }); }
3243
+ }
3244
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.3", ngImport: i0, type: ClrDatepickerModule, decorators: [{
3245
+ type: NgModule,
3246
+ args: [{
3247
+ imports: [
3248
+ CommonModule,
3249
+ CdkTrapFocusModule,
3250
+ ClrHostWrappingModule,
3251
+ ClrConditionalModule,
3252
+ ClrPopoverModuleNext,
3253
+ ClrIcon,
3254
+ ClrCommonFormsModule,
3255
+ ClrVerticalNavModule,
3256
+ ],
3257
+ declarations: [CLR_DATEPICKER_DIRECTIVES],
3258
+ exports: [CLR_DATEPICKER_DIRECTIVES],
3259
+ }]
3260
+ }], ctorParameters: () => [] });
3261
+
3262
+ /*
3263
+ * Copyright (c) 2016-2026 Broadcom. All Rights Reserved.
3264
+ * The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
3265
+ * This software is released under MIT license.
3266
+ * The full license information can be found in LICENSE in the root directory of this project.
3267
+ */
3268
+
3269
+ /**
3270
+ * Generated bundle index. Do not edit.
3271
+ */
3272
+
3273
+ export { CLR_DATEPICKER_DIRECTIVES, ClrCalendar, ClrDateContainer, ClrDateInput, ClrDateInputBase, ClrDateInputValidator, ClrDatepickerActions, ClrDatepickerModule, ClrDatepickerViewManager, ClrDay, ClrDaypicker, ClrEndDateInput, ClrEndDateInputValidator, ClrMonthpicker, ClrStartDateInput, ClrStartDateInputValidator, ClrWeekday, ClrYearpicker };
3274
+ //# sourceMappingURL=clr-angular-forms-datepicker.mjs.map