ngwr 13.0.1 → 14.0.0

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 (167) hide show
  1. package/README.md +13 -6
  2. package/color-picker/styles/_index.scss +43 -5
  3. package/fesm2022/ngwr-alert.mjs +5 -5
  4. package/fesm2022/ngwr-alert.mjs.map +1 -1
  5. package/fesm2022/ngwr-back-top.mjs +11 -1
  6. package/fesm2022/ngwr-back-top.mjs.map +1 -1
  7. package/fesm2022/ngwr-blur-text.mjs +13 -2
  8. package/fesm2022/ngwr-blur-text.mjs.map +1 -1
  9. package/fesm2022/ngwr-button.mjs +4 -4
  10. package/fesm2022/ngwr-button.mjs.map +1 -1
  11. package/fesm2022/ngwr-calendar-testing.mjs +15 -0
  12. package/fesm2022/ngwr-calendar-testing.mjs.map +1 -1
  13. package/fesm2022/ngwr-calendar.mjs +51 -5
  14. package/fesm2022/ngwr-calendar.mjs.map +1 -1
  15. package/fesm2022/ngwr-circular-text.mjs +20 -1
  16. package/fesm2022/ngwr-circular-text.mjs.map +1 -1
  17. package/fesm2022/ngwr-collapse.mjs.map +1 -1
  18. package/fesm2022/ngwr-color-picker-testing.mjs +23 -7
  19. package/fesm2022/ngwr-color-picker-testing.mjs.map +1 -1
  20. package/fesm2022/ngwr-color-picker.mjs +89 -10
  21. package/fesm2022/ngwr-color-picker.mjs.map +1 -1
  22. package/fesm2022/ngwr-command-palette.mjs +27 -3
  23. package/fesm2022/ngwr-command-palette.mjs.map +1 -1
  24. package/fesm2022/ngwr-context-menu.mjs +7 -1
  25. package/fesm2022/ngwr-context-menu.mjs.map +1 -1
  26. package/fesm2022/ngwr-date-adapters-fns.mjs +101 -33
  27. package/fesm2022/ngwr-date-adapters-fns.mjs.map +1 -1
  28. package/fesm2022/ngwr-date-picker-testing.mjs +10 -2
  29. package/fesm2022/ngwr-date-picker-testing.mjs.map +1 -1
  30. package/fesm2022/ngwr-date-picker.mjs +103 -13
  31. package/fesm2022/ngwr-date-picker.mjs.map +1 -1
  32. package/fesm2022/ngwr-date.mjs +480 -79
  33. package/fesm2022/ngwr-date.mjs.map +1 -1
  34. package/fesm2022/ngwr-drag-drop.mjs +30 -2
  35. package/fesm2022/ngwr-drag-drop.mjs.map +1 -1
  36. package/fesm2022/ngwr-dropdown.mjs +2 -1
  37. package/fesm2022/ngwr-dropdown.mjs.map +1 -1
  38. package/fesm2022/ngwr-event-calendar-testing.mjs.map +1 -1
  39. package/fesm2022/ngwr-event-calendar.mjs +1 -1
  40. package/fesm2022/ngwr-event-calendar.mjs.map +1 -1
  41. package/fesm2022/ngwr-file-upload.mjs +52 -12
  42. package/fesm2022/ngwr-file-upload.mjs.map +1 -1
  43. package/fesm2022/ngwr-i18n-en.mjs +63 -1
  44. package/fesm2022/ngwr-i18n-en.mjs.map +1 -1
  45. package/fesm2022/ngwr-i18n-ru.mjs +28 -1
  46. package/fesm2022/ngwr-i18n-ru.mjs.map +1 -1
  47. package/fesm2022/ngwr-i18n.mjs +150 -22
  48. package/fesm2022/ngwr-i18n.mjs.map +1 -1
  49. package/fesm2022/ngwr-input-number.mjs +3 -3
  50. package/fesm2022/ngwr-input-number.mjs.map +1 -1
  51. package/fesm2022/ngwr-input-otp.mjs +21 -3
  52. package/fesm2022/ngwr-input-otp.mjs.map +1 -1
  53. package/fesm2022/ngwr-input.mjs +14 -7
  54. package/fesm2022/ngwr-input.mjs.map +1 -1
  55. package/fesm2022/ngwr-knob-testing.mjs.map +1 -1
  56. package/fesm2022/ngwr-knob.mjs +20 -2
  57. package/fesm2022/ngwr-knob.mjs.map +1 -1
  58. package/fesm2022/ngwr-loading-bar-router.mjs +73 -0
  59. package/fesm2022/ngwr-loading-bar-router.mjs.map +1 -0
  60. package/fesm2022/ngwr-loading-bar.mjs +21 -32
  61. package/fesm2022/ngwr-loading-bar.mjs.map +1 -1
  62. package/fesm2022/ngwr-mention.mjs +104 -14
  63. package/fesm2022/ngwr-mention.mjs.map +1 -1
  64. package/fesm2022/ngwr-pagination-testing.mjs +11 -10
  65. package/fesm2022/ngwr-pagination-testing.mjs.map +1 -1
  66. package/fesm2022/ngwr-pagination.mjs +65 -30
  67. package/fesm2022/ngwr-pagination.mjs.map +1 -1
  68. package/fesm2022/ngwr-popconfirm.mjs +3 -2
  69. package/fesm2022/ngwr-popconfirm.mjs.map +1 -1
  70. package/fesm2022/ngwr-popover.mjs +2 -1
  71. package/fesm2022/ngwr-popover.mjs.map +1 -1
  72. package/fesm2022/ngwr-select.mjs +93 -34
  73. package/fesm2022/ngwr-select.mjs.map +1 -1
  74. package/fesm2022/ngwr-splitter-testing.mjs.map +1 -1
  75. package/fesm2022/ngwr-squircle.mjs +2 -1
  76. package/fesm2022/ngwr-squircle.mjs.map +1 -1
  77. package/fesm2022/ngwr-statistic.mjs +35 -4
  78. package/fesm2022/ngwr-statistic.mjs.map +1 -1
  79. package/fesm2022/ngwr-table.mjs +35 -12
  80. package/fesm2022/ngwr-table.mjs.map +1 -1
  81. package/fesm2022/ngwr-tabs-router.mjs +158 -0
  82. package/fesm2022/ngwr-tabs-router.mjs.map +1 -0
  83. package/fesm2022/ngwr-tabs-testing.mjs +13 -11
  84. package/fesm2022/ngwr-tabs-testing.mjs.map +1 -1
  85. package/fesm2022/ngwr-tabs.mjs +98 -10
  86. package/fesm2022/ngwr-tabs.mjs.map +1 -1
  87. package/fesm2022/ngwr-textarea.mjs +20 -1
  88. package/fesm2022/ngwr-textarea.mjs.map +1 -1
  89. package/fesm2022/ngwr-tour.mjs +1 -1
  90. package/fesm2022/ngwr-tour.mjs.map +1 -1
  91. package/fesm2022/ngwr-transfer.mjs +2 -2
  92. package/fesm2022/ngwr-transfer.mjs.map +1 -1
  93. package/fesm2022/ngwr-tree.mjs +18 -2
  94. package/fesm2022/ngwr-tree.mjs.map +1 -1
  95. package/fesm2022/ngwr-utils.mjs +37 -1
  96. package/fesm2022/ngwr-utils.mjs.map +1 -1
  97. package/fesm2022/ngwr-version.mjs +1 -1
  98. package/fesm2022/ngwr-version.mjs.map +1 -1
  99. package/fesm2022/ngwr-window-testing.mjs +10 -2
  100. package/fesm2022/ngwr-window-testing.mjs.map +1 -1
  101. package/fesm2022/ngwr-window.mjs +4 -4
  102. package/fesm2022/ngwr-window.mjs.map +1 -1
  103. package/i18n/en.json +33 -6
  104. package/i18n/ru.json +33 -6
  105. package/llms-full.txt +20 -11
  106. package/llms.txt +47 -16
  107. package/mcp/catalog.js +3 -3
  108. package/mcp/providers.js +11 -0
  109. package/package.json +9 -1
  110. package/schematics/migrations/v13/index.js +101 -0
  111. package/schematics/migrations/v14/index.js +422 -0
  112. package/schematics/migrations.json +10 -0
  113. package/schematics/page/templates.js +1 -1
  114. package/schematics/use/symbol-map.json +1 -0
  115. package/skills/ngwr/SKILL.md +4 -1
  116. package/skills/ngwr/references/catalog.md +2 -0
  117. package/skills/ngwr/references/setup.md +4 -0
  118. package/stepper/styles/_index.scss +19 -1
  119. package/textarea/styles/_index.scss +14 -6
  120. package/toast/styles/_index.scss +12 -4
  121. package/types/ngwr-alert.d.ts +3 -3
  122. package/types/ngwr-blur-text.d.ts +8 -0
  123. package/types/ngwr-button.d.ts +2 -2
  124. package/types/ngwr-calendar-testing.d.ts +21 -4
  125. package/types/ngwr-calendar.d.ts +37 -0
  126. package/types/ngwr-circular-text.d.ts +9 -0
  127. package/types/ngwr-collapse.d.ts +19 -15
  128. package/types/ngwr-color-picker-testing.d.ts +10 -4
  129. package/types/ngwr-color-picker.d.ts +70 -2
  130. package/types/ngwr-command-palette.d.ts +14 -0
  131. package/types/ngwr-context-menu.d.ts +1 -1
  132. package/types/ngwr-date-adapters-fns.d.ts +71 -29
  133. package/types/ngwr-date-picker-testing.d.ts +206 -185
  134. package/types/ngwr-date-picker.d.ts +7 -0
  135. package/types/ngwr-date.d.ts +143 -13
  136. package/types/ngwr-drag-drop.d.ts +19 -0
  137. package/types/ngwr-dropdown.d.ts +1 -1
  138. package/types/ngwr-event-calendar-testing.d.ts +12 -9
  139. package/types/ngwr-file-upload.d.ts +31 -3
  140. package/types/ngwr-i18n.d.ts +89 -7
  141. package/types/ngwr-input-number.d.ts +1 -1
  142. package/types/ngwr-input-otp.d.ts +3 -0
  143. package/types/ngwr-input.d.ts +11 -4
  144. package/types/ngwr-knob-testing.d.ts +8 -4
  145. package/types/ngwr-knob.d.ts +18 -0
  146. package/types/ngwr-loading-bar-router.d.ts +35 -0
  147. package/types/ngwr-loading-bar.d.ts +19 -9
  148. package/types/ngwr-mention.d.ts +13 -0
  149. package/types/ngwr-pagination-testing.d.ts +11 -10
  150. package/types/ngwr-pagination.d.ts +39 -10
  151. package/types/ngwr-popconfirm.d.ts +1 -1
  152. package/types/ngwr-popover.d.ts +1 -1
  153. package/types/ngwr-select.d.ts +65 -10
  154. package/types/ngwr-splitter-testing.d.ts +9 -4
  155. package/types/ngwr-squircle.d.ts +1 -1
  156. package/types/ngwr-statistic.d.ts +22 -2
  157. package/types/ngwr-table.d.ts +24 -5
  158. package/types/ngwr-tabs-router.d.ts +67 -0
  159. package/types/ngwr-tabs-testing.d.ts +12 -10
  160. package/types/ngwr-tabs.d.ts +103 -6
  161. package/types/ngwr-textarea.d.ts +9 -0
  162. package/types/ngwr-tree.d.ts +7 -0
  163. package/types/ngwr-utils.d.ts +33 -1
  164. package/types/ngwr-version.d.ts +1 -1
  165. package/types/ngwr-window-testing.d.ts +11 -3
  166. package/types/ngwr-window.d.ts +11 -4
  167. package/window/styles/_index.scss +1 -1
@@ -1,8 +1,39 @@
1
1
  import * as i0 from '@angular/core';
2
- import { inject, Service } from '@angular/core';
2
+ import { InjectionToken, inject, isDevMode, Service, makeEnvironmentProviders } from '@angular/core';
3
3
  import { isValid, getYear, getMonth, getDate, getDay, getDaysInMonth, getHours, getMinutes, getSeconds, addYears, addMonths, addDays, set, isSameDay, isSameMonth, compareAsc, startOfDay, format, parse } from 'date-fns';
4
4
  import { WrDateAdapter, WR_DATE_LOCALE, isNamedFormat, provideWrDateAdapter } from 'ngwr/date';
5
5
 
6
+ /**
7
+ * @license
8
+ *
9
+ * Use of this source code is governed by an MIT-style license that can be
10
+ * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE
11
+ */
12
+ /**
13
+ * The date-fns `Locale` OBJECT {@link WrDateFnsAdapter} formats and parses with.
14
+ *
15
+ * `WR_DATE_LOCALE` is a BCP 47 TAG, and date-fns cannot resolve a tag: its locales are
16
+ * separate modules, so mapping `'ru-RU'` onto one would mean importing all of them and
17
+ * defeating the tree-shaking that makes this an opt-in entry point. The consumer imports
18
+ * the one they need and hands it over — which is what
19
+ * {@link provideWrDateFnsAdapter}'s `dateFnsLocale` option sets.
20
+ *
21
+ * `null` (the default) passes nothing to date-fns, which leaves that library's own
22
+ * module-level default in charge — so `setDefaultOptions({ locale })` keeps working for
23
+ * apps that already use it.
24
+ *
25
+ * @example
26
+ * ```ts
27
+ * import { ru } from 'date-fns/locale/ru';
28
+ *
29
+ * provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru });
30
+ * ```
31
+ */
32
+ const WR_DATE_FNS_LOCALE = new InjectionToken('WR_DATE_FNS_LOCALE', {
33
+ providedIn: 'root',
34
+ factory: () => null,
35
+ });
36
+
6
37
  /**
7
38
  * @license
8
39
  *
@@ -23,32 +54,28 @@ const NAMED_PATTERNS = {
23
54
  * pick this when you want its long patterns (`P`, `PP`, `PPP`, `p`) without
24
55
  * writing them by hand.
25
56
  *
26
- * **{@link WR_DATE_LOCALE} does not reach `format` or `parse`, and that is not
27
- * an oversight.** date-fns resolves those patterns against a date-fns `Locale`
28
- * OBJECT rather than a BCP 47 tag, and the objects are separate modules —
29
- * mapping a tag onto one would mean importing all of them, which defeats the
30
- * tree-shaking that is the reason this is an opt-in entry point. So the named
31
- * formats render AND read in en-US whatever the tag says, while
32
- * `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through `Intl`
33
- * and do honour it: a calendar heads its columns `пн вт ср` beside a trigger
34
- * reading `08/11/2025`. Reading is the sharper edge — `11/08/2025` typed by a
35
- * user in a dd/MM locale parses as 8 November, valid and wrong.
36
- *
37
- * The lever is date-fns's own module default, and the adapter passing no locale
38
- * is precisely what keeps it working. Set it once at bootstrap, or take
39
- * `provideWrLuxonAdapter()`, which forwards the tag itself:
57
+ * **Localising it takes TWO settings, and that is a property of date-fns rather
58
+ * than a wart here.** `WR_DATE_LOCALE` is a BCP 47 tag; date-fns resolves its
59
+ * patterns against a `Locale` OBJECT, and the objects are separate modules, so
60
+ * mapping a tag onto one would mean importing all of them and defeating the
61
+ * tree-shaking that is the reason this is an opt-in entry point. Pass the object
62
+ * as `dateFnsLocale` and it reaches `format` and `parse`; leave it out and they
63
+ * stay on date-fns's own module default, which is what keeps
64
+ * `setDefaultOptions({ locale })` working for apps that already use it.
40
65
  *
41
- * ```ts
42
- * import { setDefaultOptions } from 'date-fns';
43
- * import { ru } from 'date-fns/locale';
44
- *
45
- * setDefaultOptions({ locale: ru });
46
- * ```
66
+ * Half-localising is the failure mode this is designed to make loud: with only a
67
+ * tag, `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through
68
+ * `Intl` and answer in the locale while the trigger beside them reads
69
+ * `08/11/2025`, and READING is the sharper edge — `11/08/2025` typed by a user in
70
+ * a dd/MM locale parses as 8 November, valid and wrong. A non-English tag with no
71
+ * object warns once in dev mode for exactly that reason.
47
72
  *
48
73
  * @example
49
74
  * ```ts
75
+ * import { ru } from 'date-fns/locale/ru';
76
+ *
50
77
  * bootstrapApplication(AppComponent, {
51
- * providers: [provideWrDateFnsAdapter()],
78
+ * providers: [provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru })],
52
79
  * });
53
80
  * ```
54
81
  *
@@ -56,6 +83,21 @@ const NAMED_PATTERNS = {
56
83
  */
57
84
  class WrDateFnsAdapter extends WrDateAdapter {
58
85
  locale = inject(WR_DATE_LOCALE);
86
+ dateFnsLocale = inject(WR_DATE_FNS_LOCALE);
87
+ constructor() {
88
+ super();
89
+ if (isDevMode() && !this.dateFnsLocale && !this.locale.toLowerCase().startsWith('en')) {
90
+ // eslint-disable-next-line no-console -- dev-mode validation
91
+ console.warn(`[NGWR] provideWrDateFnsAdapter({ locale: '${this.locale}' }) localises the calendar ` +
92
+ `headings but not the field: date-fns needs its own Locale OBJECT. Pass one — ` +
93
+ `provideWrDateFnsAdapter({ locale: '${this.locale}', dateFnsLocale: <import from ` +
94
+ `'date-fns/locale/…'> }) — or set date-fns's module default with setDefaultOptions().`);
95
+ }
96
+ }
97
+ /** What date-fns is handed. `{}` leaves its module default in charge. */
98
+ get options() {
99
+ return this.dateFnsLocale ? { locale: this.dateFnsLocale } : {};
100
+ }
59
101
  // Construction & identity
60
102
  today() {
61
103
  return new Date();
@@ -123,18 +165,27 @@ class WrDateFnsAdapter extends WrDateAdapter {
123
165
  // Formatting / parsing
124
166
  format(date, formatKeyOrString) {
125
167
  const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;
126
- return format(date, pattern);
168
+ return format(date, pattern, this.options);
127
169
  }
128
170
  parse(value, formatKeyOrString) {
129
171
  const raw = value?.trim();
130
172
  if (!raw)
131
173
  return null;
132
174
  const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;
133
- const result = parse(raw, pattern, new Date());
175
+ // The same options as `format`, so whatever the one wrote the other reads — the
176
+ // pattern `P` means `MM/dd/y` in enUS and `dd.MM.y` in ru, and a picker that writes
177
+ // one and reads the other is the native adapter's blocker wearing another hat.
178
+ const result = parse(raw, pattern, new Date(), this.options);
134
179
  return isValid(result) ? result : null;
135
180
  }
136
181
  // Locale info
137
182
  getFirstDayOfWeek() {
183
+ // The object wins where there is one: it is what `format` and `parse` compute with,
184
+ // and a grid starting on a different day from the strings beside it is the same
185
+ // half-localisation this adapter is trying to stop shipping.
186
+ const fromLocale = this.dateFnsLocale?.options?.weekStartsOn;
187
+ if (typeof fromLocale === 'number')
188
+ return fromLocale;
138
189
  try {
139
190
  const locale = new Intl.Locale(this.locale);
140
191
  const info = locale.getWeekInfo?.();
@@ -170,7 +221,7 @@ class WrDateFnsAdapter extends WrDateAdapter {
170
221
  }
171
222
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImport: i0, type: WrDateFnsAdapter, decorators: [{
172
223
  type: Service
173
- }] });
224
+ }], ctorParameters: () => [] });
174
225
 
175
226
  /**
176
227
  * @license
@@ -182,26 +233,43 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.4", ngImpor
182
233
  * Register the {@link WrDateFnsAdapter} so date-pickers / calendars in this
183
234
  * app use `date-fns` for all math and formatting.
184
235
  *
185
- * `locale` sets {@link WR_DATE_LOCALE}, which this adapter reads for the first
186
- * day of the week and nothing else — its `format` and `parse` do not pass a
187
- * locale to date-fns. For localized month names and patterns, set date-fns's own
188
- * module default with `setDefaultOptions`, or use the luxon adapter, which does
189
- * thread the tag through everything.
236
+ * Two locale settings, because date-fns needs a `Locale` OBJECT where the rest of the
237
+ * library needs a BCP 47 TAG:
238
+ *
239
+ * - `dateFnsLocale` — the imported object. It reaches `format` and `parse`, which is
240
+ * where the field's own text comes from, and it also decides the first day of the
241
+ * week. Leave it out and date-fns stays on its module default, so an existing
242
+ * `setDefaultOptions({ locale })` keeps working.
243
+ * - `locale` — the tag {@link WR_DATE_LOCALE} carries, read through `Intl` for the month
244
+ * and weekday NAMES. Omit it and the object's own `code` supplies it, so one import is
245
+ * enough for a fully localized picker.
246
+ *
247
+ * Passing only `locale` localizes the calendar headings and not the field, which is the
248
+ * shape of a real defect rather than a preference — the adapter warns about it once in
249
+ * dev mode.
190
250
  *
191
251
  * @example
192
252
  * ```ts
253
+ * import { ru } from 'date-fns/locale/ru';
254
+ *
193
255
  * bootstrapApplication(AppComponent, {
194
- * providers: [provideWrDateFnsAdapter()],
256
+ * providers: [provideWrDateFnsAdapter({ dateFnsLocale: ru })],
195
257
  * });
196
258
  * ```
197
259
  */
198
260
  function provideWrDateFnsAdapter(options = {}) {
199
- return provideWrDateAdapter({ adapter: WrDateFnsAdapter, locale: options.locale });
261
+ // A date-fns `Locale` carries its own tag (`ru`, `en-GB`), so one setting is enough
262
+ // and the two can never silently disagree about which language this picker is in.
263
+ const tag = options.locale ?? options.dateFnsLocale?.code;
264
+ return makeEnvironmentProviders([
265
+ provideWrDateAdapter({ adapter: WrDateFnsAdapter, locale: tag }),
266
+ ...(options.dateFnsLocale ? [{ provide: WR_DATE_FNS_LOCALE, useValue: options.dateFnsLocale }] : []),
267
+ ]);
200
268
  }
201
269
 
202
270
  /**
203
271
  * Generated bundle index. Do not edit.
204
272
  */
205
273
 
206
- export { WrDateFnsAdapter, provideWrDateFnsAdapter };
274
+ export { WR_DATE_FNS_LOCALE, WrDateFnsAdapter, provideWrDateFnsAdapter };
207
275
  //# sourceMappingURL=ngwr-date-adapters-fns.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-date-adapters-fns.mjs","sources":["../../../projects/lib/date/adapters/fns/wr-date-fns-adapter.ts","../../../projects/lib/date/adapters/fns/provide-wr-date-fns-adapter.ts","../../../projects/lib/date/adapters/fns/ngwr-date-adapters-fns.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Service, inject } from '@angular/core';\n\nimport {\n addDays as dfAddDays,\n addMonths as dfAddMonths,\n addYears as dfAddYears,\n compareAsc,\n format as dfFormat,\n getDate,\n getDay,\n getDaysInMonth,\n getHours,\n getMinutes,\n getMonth,\n getSeconds,\n getYear,\n isSameDay,\n isSameMonth,\n isValid,\n parse as dfParse,\n set as dfSet,\n startOfDay,\n} from 'date-fns';\nimport { WrDateAdapter, WR_DATE_LOCALE, type WrDateFormat, isNamedFormat } from 'ngwr/date';\n\nconst NAMED_PATTERNS: Readonly<Record<WrDateFormat, string>> = {\n shortDate: 'P',\n mediumDate: 'PP',\n longDate: 'PPP',\n time: 'p',\n shortDateTime: 'P p',\n mediumDateTime: 'PP p',\n};\n\n/**\n * {@link WrDateAdapter} backed by `date-fns`. Same `Date` value type as the\n * native adapter, but defers all math, formatting, and parsing to date-fns —\n * pick this when you want its long patterns (`P`, `PP`, `PPP`, `p`) without\n * writing them by hand.\n *\n * **{@link WR_DATE_LOCALE} does not reach `format` or `parse`, and that is not\n * an oversight.** date-fns resolves those patterns against a date-fns `Locale`\n * OBJECT rather than a BCP 47 tag, and the objects are separate modules —\n * mapping a tag onto one would mean importing all of them, which defeats the\n * tree-shaking that is the reason this is an opt-in entry point. So the named\n * formats render AND read in en-US whatever the tag says, while\n * `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through `Intl`\n * and do honour it: a calendar heads its columns `пн вт ср` beside a trigger\n * reading `08/11/2025`. Reading is the sharper edge — `11/08/2025` typed by a\n * user in a dd/MM locale parses as 8 November, valid and wrong.\n *\n * The lever is date-fns's own module default, and the adapter passing no locale\n * is precisely what keeps it working. Set it once at bootstrap, or take\n * `provideWrLuxonAdapter()`, which forwards the tag itself:\n *\n * ```ts\n * import { setDefaultOptions } from 'date-fns';\n * import { ru } from 'date-fns/locale';\n *\n * setDefaultOptions({ locale: ru });\n * ```\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrDateFnsAdapter()],\n * });\n * ```\n *\n * Peer dep: `date-fns@^3` (or `^4`).\n */\n@Service()\nexport class WrDateFnsAdapter extends WrDateAdapter<Date> {\n private readonly locale = inject(WR_DATE_LOCALE);\n\n // Construction & identity\n\n today(): Date {\n return new Date();\n }\n\n clone(date: Date): Date {\n return new Date(date.getTime());\n }\n\n createDate(year: number, month: number, day: number): Date {\n const d = new Date(year, month, day);\n if (year >= 0 && year < 100) d.setFullYear(year);\n return d;\n }\n\n isValid(date: Date): boolean {\n return isValid(date);\n }\n\n // Accessors\n\n getYear(date: Date): number {\n return getYear(date);\n }\n getMonth(date: Date): number {\n return getMonth(date);\n }\n getDate(date: Date): number {\n return getDate(date);\n }\n getDayOfWeek(date: Date): number {\n return getDay(date);\n }\n getDaysInMonth(date: Date): number {\n return getDaysInMonth(date);\n }\n getHours(date: Date): number {\n return getHours(date);\n }\n getMinutes(date: Date): number {\n return getMinutes(date);\n }\n getSeconds(date: Date): number {\n return getSeconds(date);\n }\n\n // Immutable math\n\n addYears(date: Date, amount: number): Date {\n return dfAddYears(date, amount);\n }\n addMonths(date: Date, amount: number): Date {\n return dfAddMonths(date, amount);\n }\n addDays(date: Date, amount: number): Date {\n return dfAddDays(date, amount);\n }\n setTime(date: Date, hours: number, minutes: number, seconds: number): Date {\n return dfSet(date, { hours, minutes, seconds, milliseconds: 0 });\n }\n\n // Comparison\n\n isSameDay(a: Date, b: Date): boolean {\n return isSameDay(a, b);\n }\n isSameMonth(a: Date, b: Date): boolean {\n return isSameMonth(a, b);\n }\n compareDate(a: Date, b: Date): number {\n return compareAsc(startOfDay(a), startOfDay(b));\n }\n\n // Formatting / parsing\n\n format(date: Date, formatKeyOrString: WrDateFormat | (string & {})): string {\n const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;\n return dfFormat(date, pattern);\n }\n\n parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): Date | null {\n const raw = value?.trim();\n if (!raw) return null;\n const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;\n const result = dfParse(raw, pattern, new Date());\n return isValid(result) ? result : null;\n }\n\n // Locale info\n\n getFirstDayOfWeek(): number {\n try {\n const locale = new Intl.Locale(this.locale) as unknown as { getWeekInfo?: () => { firstDay: number } };\n const info = locale.getWeekInfo?.();\n if (info && typeof info.firstDay === 'number') return info.firstDay % 7;\n } catch {\n // Intl.Locale unsupported — fall through.\n }\n return this.locale.toLowerCase().startsWith('en-us') ? 0 : 1;\n }\n\n getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: style });\n const first = this.getFirstDayOfWeek();\n const base = new Date(2024, 0, 7); // Sunday\n const out: string[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(base);\n d.setDate(base.getDate() + ((first + i) % 7));\n out.push(formatter.format(d));\n }\n return out;\n }\n\n getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: style });\n const out: string[] = [];\n for (let i = 0; i < 12; i++) out.push(formatter.format(new Date(2024, i, 15)));\n return out;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport type { EnvironmentProviders } from '@angular/core';\n\nimport { provideWrDateAdapter } from 'ngwr/date';\n\nimport { WrDateFnsAdapter } from './wr-date-fns-adapter';\n\n/**\n * Register the {@link WrDateFnsAdapter} so date-pickers / calendars in this\n * app use `date-fns` for all math and formatting.\n *\n * `locale` sets {@link WR_DATE_LOCALE}, which this adapter reads for the first\n * day of the week and nothing else — its `format` and `parse` do not pass a\n * locale to date-fns. For localized month names and patterns, set date-fns's own\n * module default with `setDefaultOptions`, or use the luxon adapter, which does\n * thread the tag through everything.\n *\n * @example\n * ```ts\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrDateFnsAdapter()],\n * });\n * ```\n */\nexport function provideWrDateFnsAdapter(options: { readonly locale?: string } = {}): EnvironmentProviders {\n return provideWrDateAdapter({ adapter: WrDateFnsAdapter, locale: options.locale });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["dfAddYears","dfAddMonths","dfAddDays","dfSet","dfFormat","dfParse"],"mappings":";;;;;AAAA;;;;;AAKG;AA2BH,MAAM,cAAc,GAA2C;AAC7D,IAAA,SAAS,EAAE,GAAG;AACd,IAAA,UAAU,EAAE,IAAI;AAChB,IAAA,QAAQ,EAAE,KAAK;AACf,IAAA,IAAI,EAAE,GAAG;AACT,IAAA,aAAa,EAAE,KAAK;AACpB,IAAA,cAAc,EAAE,MAAM;CACvB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCG;AAEG,MAAO,gBAAiB,SAAQ,aAAmB,CAAA;AACtC,IAAA,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC;;IAIhD,KAAK,GAAA;QACH,OAAO,IAAI,IAAI,EAAE;IACnB;AAEA,IAAA,KAAK,CAAC,IAAU,EAAA;QACd,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjC;AAEA,IAAA,UAAU,CAAC,IAAY,EAAE,KAAa,EAAE,GAAW,EAAA;QACjD,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC;AACpC,QAAA,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,GAAG;AAAE,YAAA,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC;AAChD,QAAA,OAAO,CAAC;IACV;AAEA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB;;AAIA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB;AACA,IAAA,QAAQ,CAAC,IAAU,EAAA;AACjB,QAAA,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB;AACA,IAAA,OAAO,CAAC,IAAU,EAAA;AAChB,QAAA,OAAO,OAAO,CAAC,IAAI,CAAC;IACtB;AACA,IAAA,YAAY,CAAC,IAAU,EAAA;AACrB,QAAA,OAAO,MAAM,CAAC,IAAI,CAAC;IACrB;AACA,IAAA,cAAc,CAAC,IAAU,EAAA;AACvB,QAAA,OAAO,cAAc,CAAC,IAAI,CAAC;IAC7B;AACA,IAAA,QAAQ,CAAC,IAAU,EAAA;AACjB,QAAA,OAAO,QAAQ,CAAC,IAAI,CAAC;IACvB;AACA,IAAA,UAAU,CAAC,IAAU,EAAA;AACnB,QAAA,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB;AACA,IAAA,UAAU,CAAC,IAAU,EAAA;AACnB,QAAA,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB;;IAIA,QAAQ,CAAC,IAAU,EAAE,MAAc,EAAA;AACjC,QAAA,OAAOA,QAAU,CAAC,IAAI,EAAE,MAAM,CAAC;IACjC;IACA,SAAS,CAAC,IAAU,EAAE,MAAc,EAAA;AAClC,QAAA,OAAOC,SAAW,CAAC,IAAI,EAAE,MAAM,CAAC;IAClC;IACA,OAAO,CAAC,IAAU,EAAE,MAAc,EAAA;AAChC,QAAA,OAAOC,OAAS,CAAC,IAAI,EAAE,MAAM,CAAC;IAChC;AACA,IAAA,OAAO,CAAC,IAAU,EAAE,KAAa,EAAE,OAAe,EAAE,OAAe,EAAA;AACjE,QAAA,OAAOC,GAAK,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;IAClE;;IAIA,SAAS,CAAC,CAAO,EAAE,CAAO,EAAA;AACxB,QAAA,OAAO,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC;IACxB;IACA,WAAW,CAAC,CAAO,EAAE,CAAO,EAAA;AAC1B,QAAA,OAAO,WAAW,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1B;IACA,WAAW,CAAC,CAAO,EAAE,CAAO,EAAA;AAC1B,QAAA,OAAO,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC;IACjD;;IAIA,MAAM,CAAC,IAAU,EAAE,iBAA+C,EAAA;AAChE,QAAA,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC,GAAG,cAAc,CAAC,iBAAiB,CAAC,GAAG,iBAAiB;AACxG,QAAA,OAAOC,MAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAChC;IAEA,KAAK,CAAC,KAAa,EAAE,iBAA+C,EAAA;AAClE,QAAA,MAAM,GAAG,GAAG,KAAK,EAAE,IAAI,EAAE;AACzB,QAAA,IAAI,CAAC,GAAG;AAAE,YAAA,OAAO,IAAI;AACrB,QAAA,MAAM,OAAO,GAAG,aAAa,CAAC,iBAAiB,CAAC,GAAG,cAAc,CAAC,iBAAiB,CAAC,GAAG,iBAAiB;AACxG,QAAA,MAAM,MAAM,GAAGC,KAAO,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;AAChD,QAAA,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI;IACxC;;IAIA,iBAAiB,GAAA;AACf,QAAA,IAAI;YACF,MAAM,MAAM,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAA4D;AACtG,YAAA,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI;AACnC,YAAA,IAAI,IAAI,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;AAAE,gBAAA,OAAO,IAAI,CAAC,QAAQ,GAAG,CAAC;QACzE;AAAE,QAAA,MAAM;;QAER;AACA,QAAA,OAAO,IAAI,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAC9D;AAEA,IAAA,iBAAiB,CAAC,KAAkC,EAAA;AAClD,QAAA,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAC1E,QAAA,MAAM,KAAK,GAAG,IAAI,CAAC,iBAAiB,EAAE;AACtC,QAAA,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAClC,MAAM,GAAG,GAAa,EAAE;AACxB,QAAA,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE;AAC1B,YAAA,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC;AACxB,YAAA,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7C,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QAC/B;AACA,QAAA,OAAO,GAAG;IACZ;AAEA,IAAA,aAAa,CAAC,KAAkC,EAAA;AAC9C,QAAA,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;QACxE,MAAM,GAAG,GAAa,EAAE;QACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE;AAAE,YAAA,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;AAC9E,QAAA,OAAO,GAAG;IACZ;uGA3HW,gBAAgB,EAAA,IAAA,EAAA,EAAA,EAAA,MAAA,EAAA,EAAA,CAAA,eAAA,CAAA,OAAA,EAAA,CAAA;wGAAhB,gBAAgB,EAAA,CAAA;;2FAAhB,gBAAgB,EAAA,UAAA,EAAA,CAAA;kBAD5B;;;AC9ED;;;;;AAKG;AAQH;;;;;;;;;;;;;;;;AAgBG;AACG,SAAU,uBAAuB,CAAC,OAAA,GAAwC,EAAE,EAAA;AAChF,IAAA,OAAO,oBAAoB,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;AACpF;;AChCA;;AAEG;;;;"}
1
+ {"version":3,"file":"ngwr-date-adapters-fns.mjs","sources":["../../../projects/lib/date/adapters/fns/tokens.ts","../../../projects/lib/date/adapters/fns/wr-date-fns-adapter.ts","../../../projects/lib/date/adapters/fns/provide-wr-date-fns-adapter.ts","../../../projects/lib/date/adapters/fns/ngwr-date-adapters-fns.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { InjectionToken } from '@angular/core';\n\nimport type { Locale } from 'date-fns';\n\n/**\n * The date-fns `Locale` OBJECT {@link WrDateFnsAdapter} formats and parses with.\n *\n * `WR_DATE_LOCALE` is a BCP 47 TAG, and date-fns cannot resolve a tag: its locales are\n * separate modules, so mapping `'ru-RU'` onto one would mean importing all of them and\n * defeating the tree-shaking that makes this an opt-in entry point. The consumer imports\n * the one they need and hands it over — which is what\n * {@link provideWrDateFnsAdapter}'s `dateFnsLocale` option sets.\n *\n * `null` (the default) passes nothing to date-fns, which leaves that library's own\n * module-level default in charge — so `setDefaultOptions({ locale })` keeps working for\n * apps that already use it.\n *\n * @example\n * ```ts\n * import { ru } from 'date-fns/locale/ru';\n *\n * provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru });\n * ```\n */\nexport const WR_DATE_FNS_LOCALE = new InjectionToken<Locale | null>('WR_DATE_FNS_LOCALE', {\n providedIn: 'root',\n factory: () => null,\n});\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { Service, inject, isDevMode } from '@angular/core';\n\nimport type { Locale } from 'date-fns';\nimport {\n addDays as dfAddDays,\n addMonths as dfAddMonths,\n addYears as dfAddYears,\n compareAsc,\n format as dfFormat,\n getDate,\n getDay,\n getDaysInMonth,\n getHours,\n getMinutes,\n getMonth,\n getSeconds,\n getYear,\n isSameDay,\n isSameMonth,\n isValid,\n parse as dfParse,\n set as dfSet,\n startOfDay,\n} from 'date-fns';\nimport { WrDateAdapter, WR_DATE_LOCALE, type WrDateFormat, isNamedFormat } from 'ngwr/date';\n\nimport { WR_DATE_FNS_LOCALE } from './tokens';\n\nconst NAMED_PATTERNS: Readonly<Record<WrDateFormat, string>> = {\n shortDate: 'P',\n mediumDate: 'PP',\n longDate: 'PPP',\n time: 'p',\n shortDateTime: 'P p',\n mediumDateTime: 'PP p',\n};\n\n/**\n * {@link WrDateAdapter} backed by `date-fns`. Same `Date` value type as the\n * native adapter, but defers all math, formatting, and parsing to date-fns —\n * pick this when you want its long patterns (`P`, `PP`, `PPP`, `p`) without\n * writing them by hand.\n *\n * **Localising it takes TWO settings, and that is a property of date-fns rather\n * than a wart here.** `WR_DATE_LOCALE` is a BCP 47 tag; date-fns resolves its\n * patterns against a `Locale` OBJECT, and the objects are separate modules, so\n * mapping a tag onto one would mean importing all of them and defeating the\n * tree-shaking that is the reason this is an opt-in entry point. Pass the object\n * as `dateFnsLocale` and it reaches `format` and `parse`; leave it out and they\n * stay on date-fns's own module default, which is what keeps\n * `setDefaultOptions({ locale })` working for apps that already use it.\n *\n * Half-localising is the failure mode this is designed to make loud: with only a\n * tag, `getFirstDayOfWeek`, `getDayOfWeekNames` and `getMonthNames` go through\n * `Intl` and answer in the locale while the trigger beside them reads\n * `08/11/2025`, and READING is the sharper edge — `11/08/2025` typed by a user in\n * a dd/MM locale parses as 8 November, valid and wrong. A non-English tag with no\n * object warns once in dev mode for exactly that reason.\n *\n * @example\n * ```ts\n * import { ru } from 'date-fns/locale/ru';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrDateFnsAdapter({ locale: 'ru-RU', dateFnsLocale: ru })],\n * });\n * ```\n *\n * Peer dep: `date-fns@^3` (or `^4`).\n */\n@Service()\nexport class WrDateFnsAdapter extends WrDateAdapter<Date> {\n private readonly locale = inject(WR_DATE_LOCALE);\n private readonly dateFnsLocale = inject(WR_DATE_FNS_LOCALE);\n\n constructor() {\n super();\n if (isDevMode() && !this.dateFnsLocale && !this.locale.toLowerCase().startsWith('en')) {\n // eslint-disable-next-line no-console -- dev-mode validation\n console.warn(\n `[NGWR] provideWrDateFnsAdapter({ locale: '${this.locale}' }) localises the calendar ` +\n `headings but not the field: date-fns needs its own Locale OBJECT. Pass one — ` +\n `provideWrDateFnsAdapter({ locale: '${this.locale}', dateFnsLocale: <import from ` +\n `'date-fns/locale/…'> }) — or set date-fns's module default with setDefaultOptions().`\n );\n }\n }\n\n /** What date-fns is handed. `{}` leaves its module default in charge. */\n private get options(): { locale?: Locale } {\n return this.dateFnsLocale ? { locale: this.dateFnsLocale } : {};\n }\n\n // Construction & identity\n\n today(): Date {\n return new Date();\n }\n\n clone(date: Date): Date {\n return new Date(date.getTime());\n }\n\n createDate(year: number, month: number, day: number): Date {\n const d = new Date(year, month, day);\n if (year >= 0 && year < 100) d.setFullYear(year);\n return d;\n }\n\n isValid(date: Date): boolean {\n return isValid(date);\n }\n\n // Accessors\n\n getYear(date: Date): number {\n return getYear(date);\n }\n getMonth(date: Date): number {\n return getMonth(date);\n }\n getDate(date: Date): number {\n return getDate(date);\n }\n getDayOfWeek(date: Date): number {\n return getDay(date);\n }\n getDaysInMonth(date: Date): number {\n return getDaysInMonth(date);\n }\n getHours(date: Date): number {\n return getHours(date);\n }\n getMinutes(date: Date): number {\n return getMinutes(date);\n }\n getSeconds(date: Date): number {\n return getSeconds(date);\n }\n\n // Immutable math\n\n addYears(date: Date, amount: number): Date {\n return dfAddYears(date, amount);\n }\n addMonths(date: Date, amount: number): Date {\n return dfAddMonths(date, amount);\n }\n addDays(date: Date, amount: number): Date {\n return dfAddDays(date, amount);\n }\n setTime(date: Date, hours: number, minutes: number, seconds: number): Date {\n return dfSet(date, { hours, minutes, seconds, milliseconds: 0 });\n }\n\n // Comparison\n\n isSameDay(a: Date, b: Date): boolean {\n return isSameDay(a, b);\n }\n isSameMonth(a: Date, b: Date): boolean {\n return isSameMonth(a, b);\n }\n compareDate(a: Date, b: Date): number {\n return compareAsc(startOfDay(a), startOfDay(b));\n }\n\n // Formatting / parsing\n\n format(date: Date, formatKeyOrString: WrDateFormat | (string & {})): string {\n const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;\n return dfFormat(date, pattern, this.options);\n }\n\n parse(value: string, formatKeyOrString: WrDateFormat | (string & {})): Date | null {\n const raw = value?.trim();\n if (!raw) return null;\n const pattern = isNamedFormat(formatKeyOrString) ? NAMED_PATTERNS[formatKeyOrString] : formatKeyOrString;\n // The same options as `format`, so whatever the one wrote the other reads — the\n // pattern `P` means `MM/dd/y` in enUS and `dd.MM.y` in ru, and a picker that writes\n // one and reads the other is the native adapter's blocker wearing another hat.\n const result = dfParse(raw, pattern, new Date(), this.options);\n return isValid(result) ? result : null;\n }\n\n // Locale info\n\n getFirstDayOfWeek(): number {\n // The object wins where there is one: it is what `format` and `parse` compute with,\n // and a grid starting on a different day from the strings beside it is the same\n // half-localisation this adapter is trying to stop shipping.\n const fromLocale = this.dateFnsLocale?.options?.weekStartsOn;\n if (typeof fromLocale === 'number') return fromLocale;\n try {\n const locale = new Intl.Locale(this.locale) as unknown as { getWeekInfo?: () => { firstDay: number } };\n const info = locale.getWeekInfo?.();\n if (info && typeof info.firstDay === 'number') return info.firstDay % 7;\n } catch {\n // Intl.Locale unsupported — fall through.\n }\n return this.locale.toLowerCase().startsWith('en-us') ? 0 : 1;\n }\n\n getDayOfWeekNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { weekday: style });\n const first = this.getFirstDayOfWeek();\n const base = new Date(2024, 0, 7); // Sunday\n const out: string[] = [];\n for (let i = 0; i < 7; i++) {\n const d = new Date(base);\n d.setDate(base.getDate() + ((first + i) % 7));\n out.push(formatter.format(d));\n }\n return out;\n }\n\n getMonthNames(style: 'narrow' | 'short' | 'long'): readonly string[] {\n const formatter = new Intl.DateTimeFormat(this.locale, { month: style });\n const out: string[] = [];\n for (let i = 0; i < 12; i++) out.push(formatter.format(new Date(2024, i, 15)));\n return out;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { type EnvironmentProviders, makeEnvironmentProviders } from '@angular/core';\n\nimport type { Locale } from 'date-fns';\nimport { provideWrDateAdapter } from 'ngwr/date';\n\nimport { WR_DATE_FNS_LOCALE } from './tokens';\nimport { WrDateFnsAdapter } from './wr-date-fns-adapter';\n\n/**\n * Register the {@link WrDateFnsAdapter} so date-pickers / calendars in this\n * app use `date-fns` for all math and formatting.\n *\n * Two locale settings, because date-fns needs a `Locale` OBJECT where the rest of the\n * library needs a BCP 47 TAG:\n *\n * - `dateFnsLocale` — the imported object. It reaches `format` and `parse`, which is\n * where the field's own text comes from, and it also decides the first day of the\n * week. Leave it out and date-fns stays on its module default, so an existing\n * `setDefaultOptions({ locale })` keeps working.\n * - `locale` — the tag {@link WR_DATE_LOCALE} carries, read through `Intl` for the month\n * and weekday NAMES. Omit it and the object's own `code` supplies it, so one import is\n * enough for a fully localized picker.\n *\n * Passing only `locale` localizes the calendar headings and not the field, which is the\n * shape of a real defect rather than a preference — the adapter warns about it once in\n * dev mode.\n *\n * @example\n * ```ts\n * import { ru } from 'date-fns/locale/ru';\n *\n * bootstrapApplication(AppComponent, {\n * providers: [provideWrDateFnsAdapter({ dateFnsLocale: ru })],\n * });\n * ```\n */\nexport function provideWrDateFnsAdapter(\n options: { readonly locale?: string; readonly dateFnsLocale?: Locale } = {}\n): EnvironmentProviders {\n // A date-fns `Locale` carries its own tag (`ru`, `en-GB`), so one setting is enough\n // and the two can never silently disagree about which language this picker is in.\n const tag = options.locale ?? options.dateFnsLocale?.code;\n\n return makeEnvironmentProviders([\n provideWrDateAdapter({ adapter: WrDateFnsAdapter, locale: tag }),\n ...(options.dateFnsLocale ? [{ provide: WR_DATE_FNS_LOCALE, useValue: options.dateFnsLocale }] : []),\n ]);\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["dfAddYears","dfAddMonths","dfAddDays","dfSet","dfFormat","dfParse"],"mappings":"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"}
@@ -151,8 +151,16 @@ async function byText(elements, text) {
151
151
  * their popup's id through the trigger's `aria-controls`, so the scoping story is
152
152
  * shared too.
153
153
  *
154
- * Not exported from the entry point — a consumer works with one of the two
155
- * concrete harnesses.
154
+ * **Deliberately not exported, and `WrAnyDatePickerHarness` is what replaces it.**
155
+ * The reason a consumer wanted this name was to write a helper taking "either
156
+ * picker", which the union in `interfaces/` says directly and without publishing
157
+ * anything else. Exporting the class instead would publish the `protected` members
158
+ * below as a subclassing contract — including `timePanels()`, which hands back the
159
+ * harness for `<wr-time-panel>`, a component this package does not ship as public
160
+ * API. A type-only re-export is not the middle ground it looks like: the base is a
161
+ * value in two `extends` clauses, so d.ts flattening promotes `export type` back to
162
+ * a value export while the FESM bundle exports nothing — an import that type-checks
163
+ * and is `undefined` at runtime.
156
164
  *
157
165
  * @internal
158
166
  */
@@ -1 +1 @@
1
- {"version":3,"file":"ngwr-date-picker-testing.mjs","sources":["../../../projects/lib/date-picker/testing/wr-date-picker-day-harness.ts","../../../projects/lib/date-picker/testing/wr-time-panel-harness.ts","../../../projects/lib/date-picker/testing/wr-date-picker-harness-base.ts","../../../projects/lib/date-picker/testing/wr-date-picker-harness.ts","../../../projects/lib/date-picker/testing/wr-date-range-picker-harness.ts","../../../projects/lib/date-picker/testing/ngwr-date-picker-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The day cell of a date-picker's calendar, under the name it shipped as.\n *\n * There is one implementation, and it lives with the component that owns the\n * element: a picker's popup IS a `<wr-calendar>`, and `.wr-calendar__day` is its\n * cell. `ngwr/calendar/testing` is therefore the home, and this alias keeps\n * `WrDatePickerDayHarness` working for every spec that already imports it — the two\n * names are the same class, so a harness from either query is usable with either.\n */\nexport { WrCalendarDayHarness as WrDatePickerDayHarness } from 'ngwr/calendar/testing';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerTimeFields } from './interfaces';\n\n/** Column order inside the stepper, which is also the order the boxes render in. */\nconst UNITS = ['hours', 'minutes', 'seconds'] as const;\n\n/** One unit of a time stepper. */\ntype Unit = (typeof UNITS)[number];\n\nfunction missingColumn(unit: Unit, method: string): string {\n return `${method}(): this stepper has no ${unit} column — seconds only render with [showSeconds]=\"true\".`;\n}\n\n/**\n * The `<wr-time-picker>` stepper inside a date-picker popup.\n *\n * Deliberately NOT exported from the entry point: the component is `@internal`\n * (`<wr-date-picker mode=\"time\">` is how a consumer gets one), so the picker\n * harnesses re-publish what it can do — `getTime()`, `setTime()`, `stepTime()`,\n * `toggleMeridiem()` — rather than handing out this class. It exists so the\n * range picker, which renders one stepper PER END, can address them\n * independently instead of by CSS nth-of-type gymnastics.\n *\n * Units are addressed by position, not by the boxes' `aria-label`: every string\n * in this panel now resolves through the i18n catalog (`datePicker.hours`,\n * `datePicker.incrementHours`, `datePicker.am` …), so keying on them would make\n * this harness answer in whatever locale the app under test is configured for.\n * Column order is the layout contract.\n *\n * @internal\n */\nexport class WrTimePanelHarness extends ComponentHarness {\n static hostSelector = '.wr-time-picker';\n\n /** The stepper's value as `HH:MM`, plus `:SS` and a space-joined {@link getMeridiem} when those columns exist. */\n async getTimeText(): Promise<string> {\n const parts = [await this.getValue('hours'), await this.getValue('minutes')];\n const seconds = await this.getOptionalValue('seconds');\n if (seconds !== null) parts.push(seconds);\n\n const meridiem = await this.getMeridiem();\n return meridiem ? `${parts.join(':')} ${meridiem}` : parts.join(':');\n }\n\n /**\n * The meridiem column's rendered text, or `null` when the stepper is in\n * 24-hour mode. `'AM'` / `'PM'` on the built-in fallbacks — it reads whatever\n * `datePicker.am` / `datePicker.pm` resolve to, so a configured catalog\n * changes the answer.\n */\n async getMeridiem(): Promise<string | null> {\n const label = await this.locatorForOptional('.wr-time-picker__label')();\n return label ? label.text() : null;\n }\n\n /**\n * Type into the boxes named by `fields`, leaving the rest alone.\n *\n * Each box is cleared and retyped rather than assigned: the panel reads an\n * emptied box as someone mid-retype and deliberately commits nothing for it, so\n * a harness that only cleared would look like a no-op.\n */\n async setFields(fields: WrDatePickerTimeFields): Promise<void> {\n for (const unit of UNITS) {\n const value = fields[unit];\n if (value === undefined) continue;\n\n const box = await this.box(unit, 'setTime');\n await box.clear();\n await box.sendKeys(String(value));\n }\n }\n\n /** Click a unit's ▲ / ▼ button once. Minutes and seconds move by the picker's `step`. */\n async step(unit: Unit, direction: 1 | -1): Promise<void> {\n // The AM/PM column contributes a ▲ and a ▼ of its own, and it is always\n // last — so it cannot be excluded by index alone: with seconds off, the\n // third ▲ in the panel IS the meridiem toggle.\n const suffix = direction === 1 ? 'up' : 'down';\n const buttons = await this.locatorForAll(\n `.wr-time-picker__col:not(.wr-time-picker__col--ampm) .wr-time-picker__step--${suffix}`\n )();\n\n const button = buttons[UNITS.indexOf(unit)];\n if (!button) throw new Error(missingColumn(unit, 'stepTime'));\n\n await button.click();\n }\n\n /** Flip AM ↔ PM. Throws on a 24-hour stepper, which has no such control. */\n async toggleMeridiem(): Promise<void> {\n const button = await this.locatorForOptional('.wr-time-picker__col--ampm .wr-time-picker__step--up')();\n if (!button) {\n throw new Error(\n 'toggleMeridiem(): this stepper has no AM / PM control — it is in 24-hour mode. Pass ' +\n 'timeFormat=\"12h\" (or a locale that resolves to 12-hour time) to get one.'\n );\n }\n\n await button.click();\n }\n\n /** A unit's rendered (zero-padded) value. */\n private async getValue(unit: Unit): Promise<string> {\n return (await this.box(unit, 'getTime')).getProperty<string>('value');\n }\n\n /** Same, but `null` when the column is not rendered at all. */\n private async getOptionalValue(unit: Unit): Promise<string | null> {\n const boxes = await this.boxes();\n const box = boxes[UNITS.indexOf(unit)];\n return box ? box.getProperty<string>('value') : null;\n }\n\n private async box(unit: Unit, method: string): Promise<TestElement> {\n const boxes = await this.boxes();\n const box = boxes[UNITS.indexOf(unit)];\n if (!box) throw new Error(missingColumn(unit, method));\n return box;\n }\n\n /** The typable boxes, in column order — the AM/PM column is a `<span>`, not one of these. */\n private async boxes(): Promise<TestElement[]> {\n return this.locatorForAll('.wr-time-picker__input')();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, type HarnessLoader, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerDayHarnessFilters } from './interfaces';\nimport { WrDatePickerDayHarness } from './wr-date-picker-day-harness';\nimport { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/** The first element whose trimmed text is exactly `text`. */\nasync function byText(elements: TestElement[], text: string): Promise<TestElement | null> {\n for (const element of elements) {\n if ((await element.text()) === text) return element;\n }\n return null;\n}\n\n/**\n * Everything `<wr-date-picker>` and `<wr-date-range-picker>` do identically: the\n * trigger button, the popup it owns, and the `<wr-calendar>` inside it. Both\n * components render the SAME trigger element (`.wr-date-picker__trigger` — the\n * range picker reuses the class rather than minting its own) and both publish\n * their popup's id through the trigger's `aria-controls`, so the scoping story is\n * shared too.\n *\n * Not exported from the entry point — a consumer works with one of the two\n * concrete harnesses.\n *\n * @internal\n */\nexport abstract class WrDatePickerHarnessBase extends ComponentHarness {\n /** Concrete class name, so errors read like the harness the caller reached for. */\n protected abstract readonly harnessName: string;\n\n /**\n * Whether the popup is up.\n *\n * Read from the trigger's `aria-expanded` rather than from a host class: unlike\n * `wr-select`, neither picker carries an `--open` modifier, and the ARIA state\n * is the thing a consumer's users actually get told.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.trigger()).getAttribute('aria-expanded')) === 'true';\n }\n\n /** Open the popup from the trigger. An already-open picker is left alone. */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.trigger()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n `${this.harnessName}.open(): the trigger did not open a popup. A disabled picker refuses to open, and so ` +\n 'does a readonly <wr-date-range-picker> — a readonly <wr-date-picker>, deliberately, still opens.'\n );\n }\n\n /**\n * Close the popup by clicking the trigger again. A closed picker is left alone.\n *\n * Deliberately not Escape: the CDK dispatches a keydown to the TOP-MOST overlay,\n * so with two pickers open this would close whichever opened last rather than\n * this one. The trigger only ever toggles its own popup.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.trigger()).click();\n }\n\n /** The popup's role — `'dialog'`, which is what the trigger's `aria-haspopup` promises. */\n async getPanelRole(): Promise<string | null> {\n return (await this.panel()).getAttribute('role');\n }\n\n /**\n * The popup's accessible name. Defaults to a catalog string chosen by `mode`\n * (\"Choose date\", \"Choose time\", …) and is overridden by `[panelAriaLabel]`.\n */\n async getPanelAriaLabel(): Promise<string | null> {\n return (await this.panel()).getAttribute('aria-label');\n }\n\n /**\n * Which of the calendar's three views is showing. The header label zooms out\n * (day → month → year); picking a month or a year zooms back in.\n */\n async getView(): Promise<'day' | 'month' | 'year'> {\n if (await this.inPanel('[role=\"grid\"]')) return 'day';\n if (await this.inPanel('.wr-calendar__months')) return 'month';\n if (await this.inPanel('.wr-calendar__years')) return 'year';\n\n throw new Error(this.noCalendar('getView'));\n }\n\n /**\n * The calendar's header: `'January 2025'` in the day view, `'2025'` in the month\n * view, `'2016 – 2027'` in the year view.\n */\n async getPanelHeader(): Promise<string> {\n const label = await this.inPanel('.wr-calendar__label');\n if (!label) throw new Error(this.noCalendar('getPanelHeader'));\n\n return label.text();\n }\n\n /** The weekday strip, in display order — `role=\"columnheader\"` cells of the grid's first row. */\n async getWeekdayLabels(): Promise<string[]> {\n const cells = await this.allInPanel('[role=\"columnheader\"]');\n if (cells.length === 0) {\n throw new Error(\n `${this.harnessName}.getWeekdayLabels(): no weekday strip. Only the day view has one, and mode=\"time\" ` +\n 'has no calendar at all.'\n );\n }\n\n return Promise.all(cells.map(cell => cell.text()));\n }\n\n /**\n * Step the calendar forwards. What one step MEANS follows the active view, as\n * the button's own `aria-label` says: a month in the day view, a year in the\n * month view, twelve years in the year view.\n */\n async next(): Promise<void> {\n await this.navigate('next');\n }\n\n /** Step the calendar backwards — see {@link next} for what one step covers. */\n async previous(): Promise<void> {\n await this.navigate('prev');\n }\n\n /**\n * Zoom out one level by clicking the header, the way a user does: day → month,\n * month → year. Throws at the year view, where the header is inert.\n */\n async zoomOut(): Promise<void> {\n const label = await this.inPanel('.wr-calendar__label');\n if (!label) throw new Error(this.noCalendar('zoomOut'));\n\n if (await label.getProperty<boolean>('disabled')) {\n throw new Error(\n `${this.harnessName}.zoomOut(): the header is inert — the calendar is already showing the year view ` +\n '(or the whole picker is disabled), and there is nothing further to zoom out to.'\n );\n }\n\n await label.click();\n }\n\n /** Pick a month in the month view, by 0-based index or by the label the calendar renders. */\n async selectMonth(month: number | string): Promise<void> {\n const chips = await this.allInPanel('.wr-calendar__months .wr-calendar__chip');\n if (chips.length === 0) {\n throw new Error(\n `${this.harnessName}.selectMonth(): the calendar is not showing its month view — call zoomOut() first.`\n );\n }\n\n const chip = typeof month === 'number' ? chips[month] : await byText(chips, month);\n if (!chip) {\n throw new Error(\n `${this.harnessName}.selectMonth(${JSON.stringify(month)}): no such month. Pass a 0-based index, or the ` +\n 'label the calendar renders — a short month name in the active locale.'\n );\n }\n\n await chip.click();\n }\n\n /** Pick a year in the year view. Only the twelve on show can be picked. */\n async selectYear(year: number): Promise<void> {\n const chips = await this.allInPanel('.wr-calendar__years .wr-calendar__chip');\n if (chips.length === 0) {\n throw new Error(\n `${this.harnessName}.selectYear(): the calendar is not showing its year view — call zoomOut() until ` +\n 'getView() answers \"year\".'\n );\n }\n\n const chip = await byText(chips, String(year));\n if (!chip) {\n const shown = await Promise.all(chips.map(candidate => candidate.text()));\n throw new Error(\n `${this.harnessName}.selectYear(${year}): the year view is showing ${shown[0]}-${shown[shown.length - 1]} ` +\n '— call previous() / next() to move the twelve-year window first.'\n );\n }\n\n await chip.click();\n }\n\n /**\n * The day cells of the calendar in this picker's popup, in DOM order — 42 of\n * them, since the grid is always six weeks and pads into the neighbouring\n * months.\n */\n async getDays(filters: WrDatePickerDayHarnessFilters = {}): Promise<WrDatePickerDayHarness[]> {\n await this.requireGrid('getDays');\n\n return (await this.panelLoader()).getAllHarnesses(WrDatePickerDayHarness.with(filters));\n }\n\n /**\n * One day of the month on show. The padding days of the neighbouring months are\n * skipped, so `getDay(1)` is the 1st of THIS month and never the 1st of the next.\n */\n async getDay(dayOfMonth: number): Promise<WrDatePickerDayHarness> {\n const cells = await this.getDays({ text: String(dayOfMonth) });\n for (const cell of cells) {\n if (!(await cell.isOutOfMonth())) return cell;\n }\n\n throw new Error(\n `${this.harnessName}.getDay(${dayOfMonth}): the month on show (${await this.getPanelHeader()}) has no such ` +\n 'day. Cells belonging to the neighbouring months are deliberately not matched — call previous() / next() ' +\n 'to change month.'\n );\n }\n\n /** Click a day of the month on show. */\n async selectDay(dayOfMonth: number): Promise<void> {\n const cell = await this.getDay(dayOfMonth);\n if (await cell.isDisabled()) {\n throw new Error(\n `${this.harnessName}.selectDay(${dayOfMonth}): that day is disabled — min / max or dateFilter rules it ` +\n 'out, and a disabled cell swallows the click rather than picking anything.'\n );\n }\n\n await cell.click();\n }\n\n /** The trigger button. Both components render it with the same class. */\n protected async trigger(): Promise<TestElement> {\n return this.locatorFor('.wr-date-picker__trigger')();\n }\n\n /**\n * The id of THIS picker's popup.\n *\n * The trigger publishes it as `aria-controls` only while the popup is up, which\n * makes one lookup answer both questions — is it open, and which of the panes\n * in the shared overlay container is ours.\n */\n protected async panelId(): Promise<string> {\n const id = await (await this.trigger()).getAttribute('aria-controls');\n if (!id) {\n throw new Error(\n `${this.harnessName}: the popup is closed — call open() first. The trigger only publishes aria-controls ` +\n 'while its popup is up.'\n );\n }\n\n return id;\n }\n\n /** A loader scoped to THIS picker's popup, so a second open picker cannot answer for it. */\n protected async panelLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /** One element inside THIS picker's popup, or `null`. */\n protected async inPanel(selector: string): Promise<TestElement | null> {\n return this.documentRootLocatorFactory().locatorForOptional(`#${await this.panelId()} ${selector}`)();\n }\n\n /** Every matching element inside THIS picker's popup, in DOM order. */\n protected async allInPanel(selector: string): Promise<TestElement[]> {\n return this.documentRootLocatorFactory().locatorForAll(`#${await this.panelId()} ${selector}`)();\n }\n\n /**\n * The time steppers in this popup, in DOM order — none in `date` mode, one for\n * `time` / `datetime`, and two (start then end) for a datetime range.\n */\n protected async timePanels(): Promise<WrTimePanelHarness[]> {\n return (await this.panelLoader()).getAllHarnesses(WrTimePanelHarness);\n }\n\n private async navigate(direction: 'prev' | 'next'): Promise<void> {\n const button = await this.inPanel(`.wr-calendar__nav--${direction}`);\n if (!button) throw new Error(this.noCalendar(direction === 'next' ? 'next' : 'previous'));\n\n await button.click();\n }\n\n /** Fail early on the day-cell methods rather than answering with an empty list. */\n private async requireGrid(method: string): Promise<void> {\n if (await this.inPanel('[role=\"grid\"]')) return;\n\n throw new Error(\n `${this.harnessName}.${method}(): this popup has no day grid. mode=\"time\" renders a time stepper only, and a ` +\n 'calendar zoomed out to its month / year view offers chips instead of day cells — selectMonth() / ' +\n 'selectYear() come back to the days.'\n );\n }\n\n private async panel(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n private noCalendar(method: string): string {\n return `${this.harnessName}.${method}(): this popup has no calendar — mode=\"time\" renders a time stepper only.`;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerHarnessFilters, WrDatePickerTimeFields } from './interfaces';\nimport { WrDatePickerHarnessBase } from './wr-date-picker-harness-base';\nimport type { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/**\n * Test harness for `<wr-date-picker>` — the `date`, `time` and `datetime` modes\n * of the one component.\n *\n * The popup is NOT inside the picker: it is a pane in the overlay container, a\n * sibling of the whole app. Everything inside it is therefore reached through the\n * document root, scoped by the id the trigger publishes as `aria-controls` —\n * which is what keeps two pickers on one page from reading each other's calendar.\n *\n * The value lives in a text field, so there are two ways in and the harness\n * offers both: {@link setValueText} types a date, {@link selectDay} picks one out\n * of the grid. There is deliberately no clear BUTTON on this component — an\n * emptied field is what clears the value, and that is what {@link clear} does.\n *\n * @example\n * ```ts\n * const picker = await loader.getHarness(WrDatePickerHarness);\n *\n * await picker.open();\n * expect(await picker.getPanelHeader()).toBe('January 2025');\n * await picker.selectDay(14);\n *\n * expect(await picker.getValueText()).toBe('14.01.2025');\n * expect(await (await picker.getDay(14)).isSelected()).toBe(true);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrDatePickerHarness extends WrDatePickerHarnessBase {\n static hostSelector = 'wr-date-picker';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrDatePickerHarnessFilters = {}): HarnessPredicate<WrDatePickerHarness> {\n return new HarnessPredicate(WrDatePickerHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getValueText(), text))\n .addOption('placeholder', options.placeholder, (harness, placeholder) =>\n HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n protected readonly harnessName = 'WrDatePickerHarness';\n\n /** Which mode the picker is in, read from the `wr-date-picker--*` modifier. */\n async getMode(): Promise<'date' | 'time' | 'datetime'> {\n const host = await this.host();\n if (await host.hasClass('wr-date-picker--time')) return 'time';\n if (await host.hasClass('wr-date-picker--datetime')) return 'datetime';\n return 'date';\n }\n\n /**\n * What the field is showing: the value in the picker's `format`, or `''` when it\n * is empty and the placeholder is up.\n */\n async getValueText(): Promise<string> {\n return (await this.field()).getProperty<string>('value');\n }\n\n /** The field's placeholder. */\n async getPlaceholder(): Promise<string> {\n return (await this.field()).getProperty<string>('placeholder');\n }\n\n /**\n * Type a date into the field, replacing whatever is there.\n *\n * The field is cleared first, so the value passes through `null` on the way —\n * exactly as it does for a user who selects all and types over it. The picker\n * parses on every keystroke and commits only when the text parses in full, so a\n * partial or out-of-bounds entry leaves the model on its last good value.\n */\n async setValueText(text: string): Promise<void> {\n const field = await this.field();\n await field.clear();\n // `sendKeys()` with an empty string throws — clearing was the whole request.\n if (text) await field.sendKeys(text);\n }\n\n /**\n * Empty the field, which clears the value.\n *\n * There is no clear button to click: unlike `wr-select`, this component ships no\n * `×` affordance, and an empty field is the documented way to get back to `null`.\n */\n async clear(): Promise<void> {\n await (await this.field()).clear();\n }\n\n /** Whether the picker refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-date-picker--disabled');\n }\n\n /**\n * Whether the field refuses typing. A read-only picker still OPENS its popup —\n * documented behaviour, and the one place it parts company with the range picker.\n */\n async isReadonly(): Promise<boolean> {\n return (await this.field()).getProperty<boolean>('readOnly');\n }\n\n /** Move focus to the field. */\n async focus(): Promise<void> {\n return (await this.field()).focus();\n }\n\n /**\n * Blur the field, which is what reformats a value to canonical and emits `touch`\n * so a bound `[formField]` can mark itself touched.\n */\n async blur(): Promise<void> {\n return (await this.field()).blur();\n }\n\n /** Whether the field currently has focus. */\n async isFocused(): Promise<boolean> {\n return (await this.field()).isFocused();\n }\n\n /**\n * The open time stepper's value as `HH:MM`, plus `:SS` when `showSeconds` is on\n * and ` AM`/` PM` in 12-hour mode.\n */\n async getTime(): Promise<string> {\n return (await this.timePanel()).getTimeText();\n }\n\n /** Type into the open time stepper's boxes. Omitted fields are left alone. */\n async setTime(fields: WrDatePickerTimeFields): Promise<void> {\n await (await this.timePanel()).setFields(fields);\n }\n\n /** Click one of the stepper's ▲ / ▼ buttons. Minutes and seconds move by `step`. */\n async stepTime(unit: 'hours' | 'minutes' | 'seconds', direction: 1 | -1): Promise<void> {\n await (await this.timePanel()).step(unit, direction);\n }\n\n /** Flip the stepper between AM and PM. Throws in 24-hour mode, which has no such control. */\n async toggleMeridiem(): Promise<void> {\n await (await this.timePanel()).toggleMeridiem();\n }\n\n private async field(): Promise<TestElement> {\n return this.locatorFor('input[wrInput]')();\n }\n\n /** The one stepper in the popup — `panelId()` has already refused a closed picker. */\n private async timePanel(): Promise<WrTimePanelHarness> {\n const [panel] = await this.timePanels();\n if (!panel) {\n throw new Error(\n `${this.harnessName}: this popup has no time stepper — mode=\"date\" renders a calendar only. Use mode=\"time\" ` +\n 'or mode=\"datetime\".'\n );\n }\n\n return panel;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerTimeFields, WrDateRangePickerHarnessFilters } from './interfaces';\nimport { WrDatePickerHarnessBase } from './wr-date-picker-harness-base';\nimport type { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/** Which end of the range a call applies to. */\ntype End = 'start' | 'end';\n\n/**\n * Test harness for `<wr-date-range-picker>` — two text fields over one range\n * calendar.\n *\n * A separate harness rather than a mode of {@link WrDatePickerHarness}, because\n * the DOM a spec has to reach is genuinely different: two fields with a separator\n * between them, and in `datetime` mode two time steppers instead of one. Every\n * call that could mean either field takes an explicit `'start'` / `'end'` — the\n * component's own bugs were nearly all \"which end did that belong to\", and a\n * harness that guessed would reproduce them.\n *\n * The popup, the calendar and the scoping work exactly as they do for the single\n * picker: a pane in the overlay container, addressed by the id the trigger\n * publishes as `aria-controls`.\n *\n * @example\n * ```ts\n * const period = await loader.getHarness(WrDateRangePickerHarness);\n *\n * await period.open();\n * await period.selectDay(14);\n * await period.selectDay(20);\n *\n * expect([await period.getStartText(), await period.getEndText()]).toEqual(['14.01.2025', '20.01.2025']);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrDateRangePickerHarness extends WrDatePickerHarnessBase {\n static hostSelector = 'wr-date-range-picker';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrDateRangePickerHarnessFilters = {}): HarnessPredicate<WrDateRangePickerHarness> {\n return new HarnessPredicate(WrDateRangePickerHarness, options)\n .addOption('startText', options.startText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getStartText(), text)\n )\n .addOption('endText', options.endText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getEndText(), text)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n protected readonly harnessName = 'WrDateRangePickerHarness';\n\n /** Which mode the picker is in, read from the `wr-date-range-picker--*` modifier. */\n async getMode(): Promise<'date' | 'datetime'> {\n return (await (await this.host()).hasClass('wr-date-range-picker--datetime')) ? 'datetime' : 'date';\n }\n\n /** What the start field is showing — `''` while that end is unpicked. */\n async getStartText(): Promise<string> {\n return (await this.field('start')).getProperty<string>('value');\n }\n\n /** What the end field is showing — `''` while that end is unpicked. */\n async getEndText(): Promise<string> {\n return (await this.field('end')).getProperty<string>('value');\n }\n\n /** The glyph rendered between the two fields (`[separator]`, `'–'` by default). */\n async getSeparator(): Promise<string> {\n return (await this.locatorFor('.wr-date-range-picker__separator')()).text();\n }\n\n /** The placeholder of one field. */\n async getPlaceholder(end: End): Promise<string> {\n return (await this.field(end)).getProperty<string>('placeholder');\n }\n\n /**\n * Type a date into the start field, replacing whatever is there.\n *\n * Ends typed out of order are NOT swapped here — the component settles the\n * ordering when the interaction is over, so call {@link blur} (or close the\n * popup) to see a normalised range.\n */\n async setStartText(text: string): Promise<void> {\n await this.type('start', text);\n }\n\n /** Type a date into the end field — see {@link setStartText} on ordering. */\n async setEndText(text: string): Promise<void> {\n await this.type('end', text);\n }\n\n /** Empty both fields, which clears the range. Neither end has a clear button. */\n async clear(): Promise<void> {\n await (await this.field('start')).clear();\n await (await this.field('end')).clear();\n }\n\n /** Whether the picker refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-date-range-picker--disabled');\n }\n\n /**\n * Whether the fields refuse typing. Stricter than `<wr-date-picker>`: a\n * read-only range picker also refuses to open, since two fields over one\n * calendar leaves no reading of \"untypeable\" that still lets the grid rewrite\n * both ends.\n */\n async isReadonly(): Promise<boolean> {\n return (await this.field('start')).getProperty<boolean>('readOnly');\n }\n\n /** Move focus to one field. */\n async focus(end: End): Promise<void> {\n return (await this.field(end)).focus();\n }\n\n /**\n * Blur one field. This is the moment an out-of-order range is put back in\n * order, and — when focus leaves the control rather than hopping to the other\n * end — the moment `touch` is emitted.\n */\n async blur(end: End): Promise<void> {\n return (await this.field(end)).blur();\n }\n\n /** Whether one field currently has focus. */\n async isFocused(end: End): Promise<boolean> {\n return (await this.field(end)).isFocused();\n }\n\n /**\n * One end's time stepper as `HH:MM`, plus `:SS` when `showSeconds` is on and\n * ` AM`/` PM` in 12-hour mode. `datetime` mode only.\n */\n async getTime(end: End): Promise<string> {\n return (await this.timePanel(end)).getTimeText();\n }\n\n /** Type into one end's time stepper. Omitted fields are left alone. */\n async setTime(end: End, fields: WrDatePickerTimeFields): Promise<void> {\n await (await this.timePanel(end)).setFields(fields);\n }\n\n /** Click one of an end's ▲ / ▼ buttons. Minutes and seconds move by `step`. */\n async stepTime(end: End, unit: 'hours' | 'minutes' | 'seconds', direction: 1 | -1): Promise<void> {\n await (await this.timePanel(end)).step(unit, direction);\n }\n\n /** Flip one end between AM and PM. Throws in 24-hour mode, which has no such control. */\n async toggleMeridiem(end: End): Promise<void> {\n await (await this.timePanel(end)).toggleMeridiem();\n }\n\n private async type(end: End, text: string): Promise<void> {\n const field = await this.field(end);\n await field.clear();\n // `sendKeys()` with an empty string throws — clearing was the whole request.\n if (text) await field.sendKeys(text);\n }\n\n /** The two fields are addressed by position, which is the order they render in. */\n private async field(end: End): Promise<TestElement> {\n const fields = await this.locatorForAll('.wr-date-range-picker__input')();\n const field = fields[end === 'start' ? 0 : 1];\n if (!field) {\n throw new Error(`${this.harnessName}: no \"${end}\" field — the picker rendered ${fields.length} of them.`);\n }\n\n return field;\n }\n\n /**\n * One end's stepper. Both are mounted together in `datetime` mode, start first —\n * the group labels are localized, so position is the addressable thing.\n */\n private async timePanel(end: End): Promise<WrTimePanelHarness> {\n const panels = await this.timePanels();\n if (panels.length === 0) {\n throw new Error(\n `${this.harnessName}: this popup has no time steppers — mode=\"date\" renders a calendar only. Use ` +\n 'mode=\"datetime\".'\n );\n }\n\n const panel = panels[end === 'start' ? 0 : 1];\n if (!panel) {\n throw new Error(`${this.harnessName}: no \"${end}\" time stepper — the popup rendered ${panels.length}.`);\n }\n\n return panel;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["WrDatePickerDayHarness"],"mappings":"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"}
1
+ {"version":3,"file":"ngwr-date-picker-testing.mjs","sources":["../../../projects/lib/date-picker/testing/wr-date-picker-day-harness.ts","../../../projects/lib/date-picker/testing/wr-time-panel-harness.ts","../../../projects/lib/date-picker/testing/wr-date-picker-harness-base.ts","../../../projects/lib/date-picker/testing/wr-date-picker-harness.ts","../../../projects/lib/date-picker/testing/wr-date-range-picker-harness.ts","../../../projects/lib/date-picker/testing/ngwr-date-picker-testing.ts"],"sourcesContent":["/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\n/**\n * The day cell of a date-picker's calendar, under the name it shipped as.\n *\n * There is one implementation, and it lives with the component that owns the\n * element: a picker's popup IS a `<wr-calendar>`, and `.wr-calendar__day` is its\n * cell. `ngwr/calendar/testing` is therefore the home, and this alias keeps\n * `WrDatePickerDayHarness` working for every spec that already imports it — the two\n * names are the same class, so a harness from either query is usable with either.\n */\nexport { WrCalendarDayHarness as WrDatePickerDayHarness } from 'ngwr/calendar/testing';\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerTimeFields } from './interfaces';\n\n/** Column order inside the stepper, which is also the order the boxes render in. */\nconst UNITS = ['hours', 'minutes', 'seconds'] as const;\n\n/** One unit of a time stepper. */\ntype Unit = (typeof UNITS)[number];\n\nfunction missingColumn(unit: Unit, method: string): string {\n return `${method}(): this stepper has no ${unit} column — seconds only render with [showSeconds]=\"true\".`;\n}\n\n/**\n * The `<wr-time-picker>` stepper inside a date-picker popup.\n *\n * Deliberately NOT exported from the entry point: the component is `@internal`\n * (`<wr-date-picker mode=\"time\">` is how a consumer gets one), so the picker\n * harnesses re-publish what it can do — `getTime()`, `setTime()`, `stepTime()`,\n * `toggleMeridiem()` — rather than handing out this class. It exists so the\n * range picker, which renders one stepper PER END, can address them\n * independently instead of by CSS nth-of-type gymnastics.\n *\n * Units are addressed by position, not by the boxes' `aria-label`: every string\n * in this panel now resolves through the i18n catalog (`datePicker.hours`,\n * `datePicker.incrementHours`, `datePicker.am` …), so keying on them would make\n * this harness answer in whatever locale the app under test is configured for.\n * Column order is the layout contract.\n *\n * @internal\n */\nexport class WrTimePanelHarness extends ComponentHarness {\n static hostSelector = '.wr-time-picker';\n\n /** The stepper's value as `HH:MM`, plus `:SS` and a space-joined {@link getMeridiem} when those columns exist. */\n async getTimeText(): Promise<string> {\n const parts = [await this.getValue('hours'), await this.getValue('minutes')];\n const seconds = await this.getOptionalValue('seconds');\n if (seconds !== null) parts.push(seconds);\n\n const meridiem = await this.getMeridiem();\n return meridiem ? `${parts.join(':')} ${meridiem}` : parts.join(':');\n }\n\n /**\n * The meridiem column's rendered text, or `null` when the stepper is in\n * 24-hour mode. `'AM'` / `'PM'` on the built-in fallbacks — it reads whatever\n * `datePicker.am` / `datePicker.pm` resolve to, so a configured catalog\n * changes the answer.\n */\n async getMeridiem(): Promise<string | null> {\n const label = await this.locatorForOptional('.wr-time-picker__label')();\n return label ? label.text() : null;\n }\n\n /**\n * Type into the boxes named by `fields`, leaving the rest alone.\n *\n * Each box is cleared and retyped rather than assigned: the panel reads an\n * emptied box as someone mid-retype and deliberately commits nothing for it, so\n * a harness that only cleared would look like a no-op.\n */\n async setFields(fields: WrDatePickerTimeFields): Promise<void> {\n for (const unit of UNITS) {\n const value = fields[unit];\n if (value === undefined) continue;\n\n const box = await this.box(unit, 'setTime');\n await box.clear();\n await box.sendKeys(String(value));\n }\n }\n\n /** Click a unit's ▲ / ▼ button once. Minutes and seconds move by the picker's `step`. */\n async step(unit: Unit, direction: 1 | -1): Promise<void> {\n // The AM/PM column contributes a ▲ and a ▼ of its own, and it is always\n // last — so it cannot be excluded by index alone: with seconds off, the\n // third ▲ in the panel IS the meridiem toggle.\n const suffix = direction === 1 ? 'up' : 'down';\n const buttons = await this.locatorForAll(\n `.wr-time-picker__col:not(.wr-time-picker__col--ampm) .wr-time-picker__step--${suffix}`\n )();\n\n const button = buttons[UNITS.indexOf(unit)];\n if (!button) throw new Error(missingColumn(unit, 'stepTime'));\n\n await button.click();\n }\n\n /** Flip AM ↔ PM. Throws on a 24-hour stepper, which has no such control. */\n async toggleMeridiem(): Promise<void> {\n const button = await this.locatorForOptional('.wr-time-picker__col--ampm .wr-time-picker__step--up')();\n if (!button) {\n throw new Error(\n 'toggleMeridiem(): this stepper has no AM / PM control — it is in 24-hour mode. Pass ' +\n 'timeFormat=\"12h\" (or a locale that resolves to 12-hour time) to get one.'\n );\n }\n\n await button.click();\n }\n\n /** A unit's rendered (zero-padded) value. */\n private async getValue(unit: Unit): Promise<string> {\n return (await this.box(unit, 'getTime')).getProperty<string>('value');\n }\n\n /** Same, but `null` when the column is not rendered at all. */\n private async getOptionalValue(unit: Unit): Promise<string | null> {\n const boxes = await this.boxes();\n const box = boxes[UNITS.indexOf(unit)];\n return box ? box.getProperty<string>('value') : null;\n }\n\n private async box(unit: Unit, method: string): Promise<TestElement> {\n const boxes = await this.boxes();\n const box = boxes[UNITS.indexOf(unit)];\n if (!box) throw new Error(missingColumn(unit, method));\n return box;\n }\n\n /** The typable boxes, in column order — the AM/PM column is a `<span>`, not one of these. */\n private async boxes(): Promise<TestElement[]> {\n return this.locatorForAll('.wr-time-picker__input')();\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { ComponentHarness, type HarnessLoader, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerDayHarnessFilters } from './interfaces';\nimport { WrDatePickerDayHarness } from './wr-date-picker-day-harness';\nimport { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/** The first element whose trimmed text is exactly `text`. */\nasync function byText(elements: TestElement[], text: string): Promise<TestElement | null> {\n for (const element of elements) {\n if ((await element.text()) === text) return element;\n }\n return null;\n}\n\n/**\n * Everything `<wr-date-picker>` and `<wr-date-range-picker>` do identically: the\n * trigger button, the popup it owns, and the `<wr-calendar>` inside it. Both\n * components render the SAME trigger element (`.wr-date-picker__trigger` — the\n * range picker reuses the class rather than minting its own) and both publish\n * their popup's id through the trigger's `aria-controls`, so the scoping story is\n * shared too.\n *\n * **Deliberately not exported, and `WrAnyDatePickerHarness` is what replaces it.**\n * The reason a consumer wanted this name was to write a helper taking \"either\n * picker\", which the union in `interfaces/` says directly and without publishing\n * anything else. Exporting the class instead would publish the `protected` members\n * below as a subclassing contract — including `timePanels()`, which hands back the\n * harness for `<wr-time-panel>`, a component this package does not ship as public\n * API. A type-only re-export is not the middle ground it looks like: the base is a\n * value in two `extends` clauses, so d.ts flattening promotes `export type` back to\n * a value export while the FESM bundle exports nothing — an import that type-checks\n * and is `undefined` at runtime.\n *\n * @internal\n */\nexport abstract class WrDatePickerHarnessBase extends ComponentHarness {\n /** Concrete class name, so errors read like the harness the caller reached for. */\n protected abstract readonly harnessName: string;\n\n /**\n * Whether the popup is up.\n *\n * Read from the trigger's `aria-expanded` rather than from a host class: unlike\n * `wr-select`, neither picker carries an `--open` modifier, and the ARIA state\n * is the thing a consumer's users actually get told.\n */\n async isOpen(): Promise<boolean> {\n return (await (await this.trigger()).getAttribute('aria-expanded')) === 'true';\n }\n\n /** Open the popup from the trigger. An already-open picker is left alone. */\n async open(): Promise<void> {\n if (await this.isOpen()) return;\n\n await (await this.trigger()).click();\n if (await this.isOpen()) return;\n\n throw new Error(\n `${this.harnessName}.open(): the trigger did not open a popup. A disabled picker refuses to open, and so ` +\n 'does a readonly <wr-date-range-picker> — a readonly <wr-date-picker>, deliberately, still opens.'\n );\n }\n\n /**\n * Close the popup by clicking the trigger again. A closed picker is left alone.\n *\n * Deliberately not Escape: the CDK dispatches a keydown to the TOP-MOST overlay,\n * so with two pickers open this would close whichever opened last rather than\n * this one. The trigger only ever toggles its own popup.\n */\n async close(): Promise<void> {\n if (!(await this.isOpen())) return;\n\n await (await this.trigger()).click();\n }\n\n /** The popup's role — `'dialog'`, which is what the trigger's `aria-haspopup` promises. */\n async getPanelRole(): Promise<string | null> {\n return (await this.panel()).getAttribute('role');\n }\n\n /**\n * The popup's accessible name. Defaults to a catalog string chosen by `mode`\n * (\"Choose date\", \"Choose time\", …) and is overridden by `[panelAriaLabel]`.\n */\n async getPanelAriaLabel(): Promise<string | null> {\n return (await this.panel()).getAttribute('aria-label');\n }\n\n /**\n * Which of the calendar's three views is showing. The header label zooms out\n * (day → month → year); picking a month or a year zooms back in.\n */\n async getView(): Promise<'day' | 'month' | 'year'> {\n if (await this.inPanel('[role=\"grid\"]')) return 'day';\n if (await this.inPanel('.wr-calendar__months')) return 'month';\n if (await this.inPanel('.wr-calendar__years')) return 'year';\n\n throw new Error(this.noCalendar('getView'));\n }\n\n /**\n * The calendar's header: `'January 2025'` in the day view, `'2025'` in the month\n * view, `'2016 – 2027'` in the year view.\n */\n async getPanelHeader(): Promise<string> {\n const label = await this.inPanel('.wr-calendar__label');\n if (!label) throw new Error(this.noCalendar('getPanelHeader'));\n\n return label.text();\n }\n\n /** The weekday strip, in display order — `role=\"columnheader\"` cells of the grid's first row. */\n async getWeekdayLabels(): Promise<string[]> {\n const cells = await this.allInPanel('[role=\"columnheader\"]');\n if (cells.length === 0) {\n throw new Error(\n `${this.harnessName}.getWeekdayLabels(): no weekday strip. Only the day view has one, and mode=\"time\" ` +\n 'has no calendar at all.'\n );\n }\n\n return Promise.all(cells.map(cell => cell.text()));\n }\n\n /**\n * Step the calendar forwards. What one step MEANS follows the active view, as\n * the button's own `aria-label` says: a month in the day view, a year in the\n * month view, twelve years in the year view.\n */\n async next(): Promise<void> {\n await this.navigate('next');\n }\n\n /** Step the calendar backwards — see {@link next} for what one step covers. */\n async previous(): Promise<void> {\n await this.navigate('prev');\n }\n\n /**\n * Zoom out one level by clicking the header, the way a user does: day → month,\n * month → year. Throws at the year view, where the header is inert.\n */\n async zoomOut(): Promise<void> {\n const label = await this.inPanel('.wr-calendar__label');\n if (!label) throw new Error(this.noCalendar('zoomOut'));\n\n if (await label.getProperty<boolean>('disabled')) {\n throw new Error(\n `${this.harnessName}.zoomOut(): the header is inert — the calendar is already showing the year view ` +\n '(or the whole picker is disabled), and there is nothing further to zoom out to.'\n );\n }\n\n await label.click();\n }\n\n /** Pick a month in the month view, by 0-based index or by the label the calendar renders. */\n async selectMonth(month: number | string): Promise<void> {\n const chips = await this.allInPanel('.wr-calendar__months .wr-calendar__chip');\n if (chips.length === 0) {\n throw new Error(\n `${this.harnessName}.selectMonth(): the calendar is not showing its month view — call zoomOut() first.`\n );\n }\n\n const chip = typeof month === 'number' ? chips[month] : await byText(chips, month);\n if (!chip) {\n throw new Error(\n `${this.harnessName}.selectMonth(${JSON.stringify(month)}): no such month. Pass a 0-based index, or the ` +\n 'label the calendar renders — a short month name in the active locale.'\n );\n }\n\n await chip.click();\n }\n\n /** Pick a year in the year view. Only the twelve on show can be picked. */\n async selectYear(year: number): Promise<void> {\n const chips = await this.allInPanel('.wr-calendar__years .wr-calendar__chip');\n if (chips.length === 0) {\n throw new Error(\n `${this.harnessName}.selectYear(): the calendar is not showing its year view — call zoomOut() until ` +\n 'getView() answers \"year\".'\n );\n }\n\n const chip = await byText(chips, String(year));\n if (!chip) {\n const shown = await Promise.all(chips.map(candidate => candidate.text()));\n throw new Error(\n `${this.harnessName}.selectYear(${year}): the year view is showing ${shown[0]}-${shown[shown.length - 1]} ` +\n '— call previous() / next() to move the twelve-year window first.'\n );\n }\n\n await chip.click();\n }\n\n /**\n * The day cells of the calendar in this picker's popup, in DOM order — 42 of\n * them, since the grid is always six weeks and pads into the neighbouring\n * months.\n */\n async getDays(filters: WrDatePickerDayHarnessFilters = {}): Promise<WrDatePickerDayHarness[]> {\n await this.requireGrid('getDays');\n\n return (await this.panelLoader()).getAllHarnesses(WrDatePickerDayHarness.with(filters));\n }\n\n /**\n * One day of the month on show. The padding days of the neighbouring months are\n * skipped, so `getDay(1)` is the 1st of THIS month and never the 1st of the next.\n */\n async getDay(dayOfMonth: number): Promise<WrDatePickerDayHarness> {\n const cells = await this.getDays({ text: String(dayOfMonth) });\n for (const cell of cells) {\n if (!(await cell.isOutOfMonth())) return cell;\n }\n\n throw new Error(\n `${this.harnessName}.getDay(${dayOfMonth}): the month on show (${await this.getPanelHeader()}) has no such ` +\n 'day. Cells belonging to the neighbouring months are deliberately not matched — call previous() / next() ' +\n 'to change month.'\n );\n }\n\n /** Click a day of the month on show. */\n async selectDay(dayOfMonth: number): Promise<void> {\n const cell = await this.getDay(dayOfMonth);\n if (await cell.isDisabled()) {\n throw new Error(\n `${this.harnessName}.selectDay(${dayOfMonth}): that day is disabled — min / max or dateFilter rules it ` +\n 'out, and a disabled cell swallows the click rather than picking anything.'\n );\n }\n\n await cell.click();\n }\n\n /** The trigger button. Both components render it with the same class. */\n protected async trigger(): Promise<TestElement> {\n return this.locatorFor('.wr-date-picker__trigger')();\n }\n\n /**\n * The id of THIS picker's popup.\n *\n * The trigger publishes it as `aria-controls` only while the popup is up, which\n * makes one lookup answer both questions — is it open, and which of the panes\n * in the shared overlay container is ours.\n */\n protected async panelId(): Promise<string> {\n const id = await (await this.trigger()).getAttribute('aria-controls');\n if (!id) {\n throw new Error(\n `${this.harnessName}: the popup is closed — call open() first. The trigger only publishes aria-controls ` +\n 'while its popup is up.'\n );\n }\n\n return id;\n }\n\n /** A loader scoped to THIS picker's popup, so a second open picker cannot answer for it. */\n protected async panelLoader(): Promise<HarnessLoader> {\n return this.documentRootLocatorFactory().harnessLoaderFor(`#${await this.panelId()}`);\n }\n\n /** One element inside THIS picker's popup, or `null`. */\n protected async inPanel(selector: string): Promise<TestElement | null> {\n return this.documentRootLocatorFactory().locatorForOptional(`#${await this.panelId()} ${selector}`)();\n }\n\n /** Every matching element inside THIS picker's popup, in DOM order. */\n protected async allInPanel(selector: string): Promise<TestElement[]> {\n return this.documentRootLocatorFactory().locatorForAll(`#${await this.panelId()} ${selector}`)();\n }\n\n /**\n * The time steppers in this popup, in DOM order — none in `date` mode, one for\n * `time` / `datetime`, and two (start then end) for a datetime range.\n */\n protected async timePanels(): Promise<WrTimePanelHarness[]> {\n return (await this.panelLoader()).getAllHarnesses(WrTimePanelHarness);\n }\n\n private async navigate(direction: 'prev' | 'next'): Promise<void> {\n const button = await this.inPanel(`.wr-calendar__nav--${direction}`);\n if (!button) throw new Error(this.noCalendar(direction === 'next' ? 'next' : 'previous'));\n\n await button.click();\n }\n\n /** Fail early on the day-cell methods rather than answering with an empty list. */\n private async requireGrid(method: string): Promise<void> {\n if (await this.inPanel('[role=\"grid\"]')) return;\n\n throw new Error(\n `${this.harnessName}.${method}(): this popup has no day grid. mode=\"time\" renders a time stepper only, and a ` +\n 'calendar zoomed out to its month / year view offers chips instead of day cells — selectMonth() / ' +\n 'selectYear() come back to the days.'\n );\n }\n\n private async panel(): Promise<TestElement> {\n return this.documentRootLocatorFactory().locatorFor(`#${await this.panelId()}`)();\n }\n\n private noCalendar(method: string): string {\n return `${this.harnessName}.${method}(): this popup has no calendar — mode=\"time\" renders a time stepper only.`;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerHarnessFilters, WrDatePickerTimeFields } from './interfaces';\nimport { WrDatePickerHarnessBase } from './wr-date-picker-harness-base';\nimport type { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/**\n * Test harness for `<wr-date-picker>` — the `date`, `time` and `datetime` modes\n * of the one component.\n *\n * The popup is NOT inside the picker: it is a pane in the overlay container, a\n * sibling of the whole app. Everything inside it is therefore reached through the\n * document root, scoped by the id the trigger publishes as `aria-controls` —\n * which is what keeps two pickers on one page from reading each other's calendar.\n *\n * The value lives in a text field, so there are two ways in and the harness\n * offers both: {@link setValueText} types a date, {@link selectDay} picks one out\n * of the grid. There is deliberately no clear BUTTON on this component — an\n * emptied field is what clears the value, and that is what {@link clear} does.\n *\n * @example\n * ```ts\n * const picker = await loader.getHarness(WrDatePickerHarness);\n *\n * await picker.open();\n * expect(await picker.getPanelHeader()).toBe('January 2025');\n * await picker.selectDay(14);\n *\n * expect(await picker.getValueText()).toBe('14.01.2025');\n * expect(await (await picker.getDay(14)).isSelected()).toBe(true);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrDatePickerHarness extends WrDatePickerHarnessBase {\n static hostSelector = 'wr-date-picker';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrDatePickerHarnessFilters = {}): HarnessPredicate<WrDatePickerHarness> {\n return new HarnessPredicate(WrDatePickerHarness, options)\n .addOption('text', options.text, (harness, text) => HarnessPredicate.stringMatches(harness.getValueText(), text))\n .addOption('placeholder', options.placeholder, (harness, placeholder) =>\n HarnessPredicate.stringMatches(harness.getPlaceholder(), placeholder)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n protected readonly harnessName = 'WrDatePickerHarness';\n\n /** Which mode the picker is in, read from the `wr-date-picker--*` modifier. */\n async getMode(): Promise<'date' | 'time' | 'datetime'> {\n const host = await this.host();\n if (await host.hasClass('wr-date-picker--time')) return 'time';\n if (await host.hasClass('wr-date-picker--datetime')) return 'datetime';\n return 'date';\n }\n\n /**\n * What the field is showing: the value in the picker's `format`, or `''` when it\n * is empty and the placeholder is up.\n */\n async getValueText(): Promise<string> {\n return (await this.field()).getProperty<string>('value');\n }\n\n /** The field's placeholder. */\n async getPlaceholder(): Promise<string> {\n return (await this.field()).getProperty<string>('placeholder');\n }\n\n /**\n * Type a date into the field, replacing whatever is there.\n *\n * The field is cleared first, so the value passes through `null` on the way —\n * exactly as it does for a user who selects all and types over it. The picker\n * parses on every keystroke and commits only when the text parses in full, so a\n * partial or out-of-bounds entry leaves the model on its last good value.\n */\n async setValueText(text: string): Promise<void> {\n const field = await this.field();\n await field.clear();\n // `sendKeys()` with an empty string throws — clearing was the whole request.\n if (text) await field.sendKeys(text);\n }\n\n /**\n * Empty the field, which clears the value.\n *\n * There is no clear button to click: unlike `wr-select`, this component ships no\n * `×` affordance, and an empty field is the documented way to get back to `null`.\n */\n async clear(): Promise<void> {\n await (await this.field()).clear();\n }\n\n /** Whether the picker refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-date-picker--disabled');\n }\n\n /**\n * Whether the field refuses typing. A read-only picker still OPENS its popup —\n * documented behaviour, and the one place it parts company with the range picker.\n */\n async isReadonly(): Promise<boolean> {\n return (await this.field()).getProperty<boolean>('readOnly');\n }\n\n /** Move focus to the field. */\n async focus(): Promise<void> {\n return (await this.field()).focus();\n }\n\n /**\n * Blur the field, which is what reformats a value to canonical and emits `touch`\n * so a bound `[formField]` can mark itself touched.\n */\n async blur(): Promise<void> {\n return (await this.field()).blur();\n }\n\n /** Whether the field currently has focus. */\n async isFocused(): Promise<boolean> {\n return (await this.field()).isFocused();\n }\n\n /**\n * The open time stepper's value as `HH:MM`, plus `:SS` when `showSeconds` is on\n * and ` AM`/` PM` in 12-hour mode.\n */\n async getTime(): Promise<string> {\n return (await this.timePanel()).getTimeText();\n }\n\n /** Type into the open time stepper's boxes. Omitted fields are left alone. */\n async setTime(fields: WrDatePickerTimeFields): Promise<void> {\n await (await this.timePanel()).setFields(fields);\n }\n\n /** Click one of the stepper's ▲ / ▼ buttons. Minutes and seconds move by `step`. */\n async stepTime(unit: 'hours' | 'minutes' | 'seconds', direction: 1 | -1): Promise<void> {\n await (await this.timePanel()).step(unit, direction);\n }\n\n /** Flip the stepper between AM and PM. Throws in 24-hour mode, which has no such control. */\n async toggleMeridiem(): Promise<void> {\n await (await this.timePanel()).toggleMeridiem();\n }\n\n private async field(): Promise<TestElement> {\n return this.locatorFor('input[wrInput]')();\n }\n\n /** The one stepper in the popup — `panelId()` has already refused a closed picker. */\n private async timePanel(): Promise<WrTimePanelHarness> {\n const [panel] = await this.timePanels();\n if (!panel) {\n throw new Error(\n `${this.harnessName}: this popup has no time stepper — mode=\"date\" renders a calendar only. Use mode=\"time\" ` +\n 'or mode=\"datetime\".'\n );\n }\n\n return panel;\n }\n}\n","/**\n * @license\n *\n * Use of this source code is governed by an MIT-style license that can be\n * found in the LICENSE file at https://github.com/thekhegay/ngwr/blob/main/LICENSE\n */\n\nimport { HarnessPredicate, type TestElement } from '@angular/cdk/testing';\n\nimport type { WrDatePickerTimeFields, WrDateRangePickerEnd, WrDateRangePickerHarnessFilters } from './interfaces';\nimport { WrDatePickerHarnessBase } from './wr-date-picker-harness-base';\nimport type { WrTimePanelHarness } from './wr-time-panel-harness';\n\n/**\n * Test harness for `<wr-date-range-picker>` — two text fields over one range\n * calendar.\n *\n * A separate harness rather than a mode of {@link WrDatePickerHarness}, because\n * the DOM a spec has to reach is genuinely different: two fields with a separator\n * between them, and in `datetime` mode two time steppers instead of one. Every\n * call that could mean either field takes an explicit `'start'` / `'end'` — the\n * component's own bugs were nearly all \"which end did that belong to\", and a\n * harness that guessed would reproduce them.\n *\n * The popup, the calendar and the scoping work exactly as they do for the single\n * picker: a pane in the overlay container, addressed by the id the trigger\n * publishes as `aria-controls`.\n *\n * @example\n * ```ts\n * const period = await loader.getHarness(WrDateRangePickerHarness);\n *\n * await period.open();\n * await period.selectDay(14);\n * await period.selectDay(20);\n *\n * expect([await period.getStartText(), await period.getEndText()]).toEqual(['14.01.2025', '20.01.2025']);\n * ```\n *\n * @see https://ngwr.dev/guides/testing\n */\nexport class WrDateRangePickerHarness extends WrDatePickerHarnessBase {\n static hostSelector = 'wr-date-range-picker';\n\n /** Build a predicate that narrows the query. */\n static with(options: WrDateRangePickerHarnessFilters = {}): HarnessPredicate<WrDateRangePickerHarness> {\n return new HarnessPredicate(WrDateRangePickerHarness, options)\n .addOption('startText', options.startText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getStartText(), text)\n )\n .addOption('endText', options.endText, (harness, text) =>\n HarnessPredicate.stringMatches(harness.getEndText(), text)\n )\n .addOption('mode', options.mode, async (harness, mode) => (await harness.getMode()) === mode)\n .addOption('disabled', options.disabled, async (harness, disabled) => (await harness.isDisabled()) === disabled)\n .addOption('open', options.open, async (harness, open) => (await harness.isOpen()) === open);\n }\n\n protected readonly harnessName = 'WrDateRangePickerHarness';\n\n /** Which mode the picker is in, read from the `wr-date-range-picker--*` modifier. */\n async getMode(): Promise<'date' | 'datetime'> {\n return (await (await this.host()).hasClass('wr-date-range-picker--datetime')) ? 'datetime' : 'date';\n }\n\n /** What the start field is showing — `''` while that end is unpicked. */\n async getStartText(): Promise<string> {\n return (await this.field('start')).getProperty<string>('value');\n }\n\n /** What the end field is showing — `''` while that end is unpicked. */\n async getEndText(): Promise<string> {\n return (await this.field('end')).getProperty<string>('value');\n }\n\n /** The glyph rendered between the two fields (`[separator]`, `'–'` by default). */\n async getSeparator(): Promise<string> {\n return (await this.locatorFor('.wr-date-range-picker__separator')()).text();\n }\n\n /** The placeholder of one field. */\n async getPlaceholder(end: WrDateRangePickerEnd): Promise<string> {\n return (await this.field(end)).getProperty<string>('placeholder');\n }\n\n /**\n * Type a date into the start field, replacing whatever is there.\n *\n * Ends typed out of order are NOT swapped here — the component settles the\n * ordering when the interaction is over, so call {@link blur} (or close the\n * popup) to see a normalised range.\n */\n async setStartText(text: string): Promise<void> {\n await this.type('start', text);\n }\n\n /** Type a date into the end field — see {@link setStartText} on ordering. */\n async setEndText(text: string): Promise<void> {\n await this.type('end', text);\n }\n\n /** Empty both fields, which clears the range. Neither end has a clear button. */\n async clear(): Promise<void> {\n await (await this.field('start')).clear();\n await (await this.field('end')).clear();\n }\n\n /** Whether the picker refuses interaction. */\n async isDisabled(): Promise<boolean> {\n return (await this.host()).hasClass('wr-date-range-picker--disabled');\n }\n\n /**\n * Whether the fields refuse typing. Stricter than `<wr-date-picker>`: a\n * read-only range picker also refuses to open, since two fields over one\n * calendar leaves no reading of \"untypeable\" that still lets the grid rewrite\n * both ends.\n */\n async isReadonly(): Promise<boolean> {\n return (await this.field('start')).getProperty<boolean>('readOnly');\n }\n\n /** Move focus to one field. */\n async focus(end: WrDateRangePickerEnd): Promise<void> {\n return (await this.field(end)).focus();\n }\n\n /**\n * Blur one field. This is the moment an out-of-order range is put back in\n * order, and — when focus leaves the control rather than hopping to the other\n * end — the moment `touch` is emitted.\n */\n async blur(end: WrDateRangePickerEnd): Promise<void> {\n return (await this.field(end)).blur();\n }\n\n /** Whether one field currently has focus. */\n async isFocused(end: WrDateRangePickerEnd): Promise<boolean> {\n return (await this.field(end)).isFocused();\n }\n\n /**\n * One end's time stepper as `HH:MM`, plus `:SS` when `showSeconds` is on and\n * ` AM`/` PM` in 12-hour mode. `datetime` mode only.\n */\n async getTime(end: WrDateRangePickerEnd): Promise<string> {\n return (await this.timePanel(end)).getTimeText();\n }\n\n /** Type into one end's time stepper. Omitted fields are left alone. */\n async setTime(end: WrDateRangePickerEnd, fields: WrDatePickerTimeFields): Promise<void> {\n await (await this.timePanel(end)).setFields(fields);\n }\n\n /** Click one of an end's ▲ / ▼ buttons. Minutes and seconds move by `step`. */\n async stepTime(end: WrDateRangePickerEnd, unit: 'hours' | 'minutes' | 'seconds', direction: 1 | -1): Promise<void> {\n await (await this.timePanel(end)).step(unit, direction);\n }\n\n /** Flip one end between AM and PM. Throws in 24-hour mode, which has no such control. */\n async toggleMeridiem(end: WrDateRangePickerEnd): Promise<void> {\n await (await this.timePanel(end)).toggleMeridiem();\n }\n\n private async type(end: WrDateRangePickerEnd, text: string): Promise<void> {\n const field = await this.field(end);\n await field.clear();\n // `sendKeys()` with an empty string throws — clearing was the whole request.\n if (text) await field.sendKeys(text);\n }\n\n /** The two fields are addressed by position, which is the order they render in. */\n private async field(end: WrDateRangePickerEnd): Promise<TestElement> {\n const fields = await this.locatorForAll('.wr-date-range-picker__input')();\n const field = fields[end === 'start' ? 0 : 1];\n if (!field) {\n throw new Error(`${this.harnessName}: no \"${end}\" field — the picker rendered ${fields.length} of them.`);\n }\n\n return field;\n }\n\n /**\n * One end's stepper. Both are mounted together in `datetime` mode, start first —\n * the group labels are localized, so position is the addressable thing.\n */\n private async timePanel(end: WrDateRangePickerEnd): Promise<WrTimePanelHarness> {\n const panels = await this.timePanels();\n if (panels.length === 0) {\n throw new Error(\n `${this.harnessName}: this popup has no time steppers — mode=\"date\" renders a calendar only. Use ` +\n 'mode=\"datetime\".'\n );\n }\n\n const panel = panels[end === 'start' ? 0 : 1];\n if (!panel) {\n throw new Error(`${this.harnessName}: no \"${end}\" time stepper — the popup rendered ${panels.length}.`);\n }\n\n return panel;\n }\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["WrDatePickerDayHarness"],"mappings":"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"}