@wkly/datetime-picker 12.0.0 → 13.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 (60) hide show
  1. package/cdk-overlay/package.json +5 -6
  2. package/cdk-overlay/public-api.d.ts +10 -0
  3. package/cdk-overlay/wkly-datetime-picker-cdk-overlay.d.ts +1 -0
  4. package/config.d.ts +3 -0
  5. package/esm2020/cdk-overlay/public-api.mjs +137 -0
  6. package/{esm2015/cdk-overlay/wkly-datetime-picker-cdk-overlay.js → esm2020/cdk-overlay/wkly-datetime-picker-cdk-overlay.mjs} +1 -1
  7. package/esm2020/config.mjs +100 -0
  8. package/esm2020/field.component.mjs +253 -0
  9. package/esm2020/picker.component.mjs +955 -0
  10. package/esm2020/presentation.mjs +303 -0
  11. package/esm2020/public-api.mjs +31 -0
  12. package/{esm2015/wkly-datetime-picker.js → esm2020/wkly-datetime-picker.mjs} +1 -1
  13. package/fesm2015/wkly-datetime-picker-cdk-overlay.mjs +143 -0
  14. package/fesm2015/wkly-datetime-picker-cdk-overlay.mjs.map +1 -0
  15. package/fesm2015/wkly-datetime-picker.mjs +1624 -0
  16. package/fesm2015/wkly-datetime-picker.mjs.map +1 -0
  17. package/fesm2020/wkly-datetime-picker-cdk-overlay.mjs +143 -0
  18. package/fesm2020/wkly-datetime-picker-cdk-overlay.mjs.map +1 -0
  19. package/fesm2020/wkly-datetime-picker.mjs +1622 -0
  20. package/fesm2020/wkly-datetime-picker.mjs.map +1 -0
  21. package/field.component.d.ts +3 -0
  22. package/package.json +34 -14
  23. package/picker.component.d.ts +3 -0
  24. package/presentation.d.ts +7 -0
  25. package/public-api.d.ts +8 -0
  26. package/wkly-datetime-picker.d.ts +1 -1
  27. package/bundles/wkly-datetime-picker-cdk-overlay.umd.js +0 -675
  28. package/bundles/wkly-datetime-picker-cdk-overlay.umd.js.map +0 -1
  29. package/bundles/wkly-datetime-picker.umd.js +0 -2373
  30. package/bundles/wkly-datetime-picker.umd.js.map +0 -1
  31. package/cdk-overlay/public-api.ngfactory.d.ts +0 -3
  32. package/cdk-overlay/wkly-datetime-picker-cdk-overlay.metadata.json +0 -1
  33. package/esm2015/cdk-overlay/public-api.js +0 -127
  34. package/esm2015/cdk-overlay/public-api.ngfactory.js +0 -19
  35. package/esm2015/cdk-overlay/public-api.ngsummary.json +0 -1
  36. package/esm2015/cdk-overlay/wkly-datetime-picker-cdk-overlay.ngsummary.json +0 -1
  37. package/esm2015/config.js +0 -241
  38. package/esm2015/config.ngsummary.json +0 -1
  39. package/esm2015/field.component.css.shim.ngstyle.js +0 -9
  40. package/esm2015/field.component.js +0 -240
  41. package/esm2015/field.component.ngfactory.js +0 -52
  42. package/esm2015/field.component.ngsummary.json +0 -1
  43. package/esm2015/picker.component.js +0 -929
  44. package/esm2015/picker.component.ngfactory.js +0 -137
  45. package/esm2015/picker.component.ngsummary.json +0 -1
  46. package/esm2015/presentation.js +0 -295
  47. package/esm2015/presentation.ngsummary.json +0 -1
  48. package/esm2015/public-api.js +0 -24
  49. package/esm2015/public-api.ngfactory.js +0 -13
  50. package/esm2015/public-api.ngsummary.json +0 -1
  51. package/esm2015/wkly-datetime-picker.ngsummary.json +0 -1
  52. package/fesm2015/wkly-datetime-picker-cdk-overlay.js +0 -134
  53. package/fesm2015/wkly-datetime-picker-cdk-overlay.js.map +0 -1
  54. package/fesm2015/wkly-datetime-picker.js +0 -1715
  55. package/fesm2015/wkly-datetime-picker.js.map +0 -1
  56. package/field.component.css.shim.ngstyle.d.ts +0 -1
  57. package/field.component.ngfactory.d.ts +0 -1
  58. package/picker.component.ngfactory.d.ts +0 -1
  59. package/public-api.ngfactory.d.ts +0 -3
  60. package/wkly-datetime-picker.metadata.json +0 -1
@@ -0,0 +1,1622 @@
1
+ import * as i0 from '@angular/core';
2
+ import { InjectionToken, EventEmitter, Directive, Component, Input, Output, LOCALE_ID, PLATFORM_ID, forwardRef, Inject, ViewChild, Injectable, HostListener, NgModule } from '@angular/core';
3
+ import * as i2 from '@angular/common';
4
+ import { isPlatformBrowser, getLocaleFirstDayOfWeek, DOCUMENT, CommonModule } from '@angular/common';
5
+ import { NG_VALUE_ACCESSOR, NG_VALIDATORS } from '@angular/forms';
6
+ import { floorMod, integer, createWeekGenerator, absoluteWeekOf, firstEpochDayOf } from '@wkly/core';
7
+ import { normalizeDigits, WklyGregorianCalendarAdapter, resolveWeekOffset, error, validateSelection, decodeIso } from '@wkly/adapters';
8
+ import { DEFAULT_OVERSCAN_WEEKS, WklyPickerInputsPropertyKeys, WklyPickerOutputsPropertyKeys, coerceBoolean, resolveWklyTranslation, validateDrafts, draftDayDifference, setDraftDayDifference, calendarMonthBounds, createWeekRows, INPUT_NAMES } from '@wkly/presentation';
9
+ export * from '@wkly/presentation';
10
+
11
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
12
+ const WKLY_CLOCK = new InjectionToken("WKLY_CLOCK", {
13
+ providedIn: "root",
14
+ factory: () => ({ now: () => new Date() }),
15
+ });
16
+ const WKLY_CONFIG = new InjectionToken("WKLY_CONFIG", { providedIn: "root", factory: () => ({}) });
17
+ const WKLY_LOCALIZATION = new InjectionToken("WKLY_LOCALIZATION", { providedIn: "root", factory: () => ({}) });
18
+ const WKLY_TRANSLATIONS = new InjectionToken("WKLY_TRANSLATIONS", { providedIn: "root", factory: () => ({}) });
19
+ /** Shared public inputs/outputs inherited by the picker and both trigger directives. */
20
+ // Inherited inputs need literal names in published decorator metadata.
21
+ class WklyPickerInputs {
22
+ constructor() {
23
+ this[_a] = "datetime";
24
+ this[_b] = null;
25
+ this[_c] = "";
26
+ this[_d] = null;
27
+ this[_e] = {
28
+ kind: "full-month",
29
+ };
30
+ this[_f] = "locale";
31
+ this[_g] = false;
32
+ this[_h] = 1;
33
+ this[_j] = 1;
34
+ this[_k] = null;
35
+ this[_l] = null;
36
+ this[_m] = null;
37
+ this[_o] = null;
38
+ this[_p] = null;
39
+ this[_q] = false;
40
+ this[_r] = false;
41
+ this[_s] = false;
42
+ this[_t] = "locale";
43
+ this[_u] = null;
44
+ this[_v] = 256;
45
+ this[_w] = DEFAULT_OVERSCAN_WEEKS;
46
+ this[_x] = null;
47
+ this[_y] = null;
48
+ this[_z] = null;
49
+ this[_0] = true;
50
+ this[_1] = [];
51
+ this[_2] = null;
52
+ this[_3] = new EventEmitter();
53
+ this[_4] = new EventEmitter(true);
54
+ this[_5] = new EventEmitter();
55
+ this[_6] = new EventEmitter();
56
+ this[_7] = new EventEmitter(true);
57
+ this[_8] = new EventEmitter();
58
+ }
59
+ }
60
+ _a = WklyPickerInputsPropertyKeys.Mode, _b = WklyPickerInputsPropertyKeys.Value, WklyPickerInputsPropertyKeys.CalendarAdapter, _c = WklyPickerInputsPropertyKeys.Locale, _d = WklyPickerInputsPropertyKeys.WeekOffset, _e = WklyPickerInputsPropertyKeys.ViewportPreset, _f = WklyPickerInputsPropertyKeys.HourCycle, _g = WklyPickerInputsPropertyKeys.ShowSeconds, _h = WklyPickerInputsPropertyKeys.MinuteStep, _j = WklyPickerInputsPropertyKeys.SecondStep, _k = WklyPickerInputsPropertyKeys.Min, _l = WklyPickerInputsPropertyKeys.Max, _m = WklyPickerInputsPropertyKeys.IsDateDisabled, _o = WklyPickerInputsPropertyKeys.IsTimeDisabled, _p = WklyPickerInputsPropertyKeys.RangeValidator, _q = WklyPickerInputsPropertyKeys.AllowRangeAcrossDisabled, _r = WklyPickerInputsPropertyKeys.Required, _s = WklyPickerInputsPropertyKeys.Disabled, _t = WklyPickerInputsPropertyKeys.WeekLabelMode, _u = WklyPickerInputsPropertyKeys.WeekLabelFormatter, _v = WklyPickerInputsPropertyKeys.WeekCacheSize, _w = WklyPickerInputsPropertyKeys.OverscanWeeks, _x = WklyPickerInputsPropertyKeys.AriaLabel, _y = WklyPickerInputsPropertyKeys.AriaDescribedBy, _z = WklyPickerInputsPropertyKeys.InitialEpochDay, _0 = WklyPickerInputsPropertyKeys.CloseOnBackdrop, _1 = WklyPickerInputsPropertyKeys.Validators, _2 = WklyPickerInputsPropertyKeys.Translations, _3 = WklyPickerOutputsPropertyKeys.ValueChange, _4 = WklyPickerOutputsPropertyKeys.ValidationChange, _5 = WklyPickerOutputsPropertyKeys.Opened, _6 = WklyPickerOutputsPropertyKeys.Closed, _7 = WklyPickerOutputsPropertyKeys.ViewportChange, _8 = WklyPickerOutputsPropertyKeys.ViewModeChange;
61
+ WklyPickerInputs.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyPickerInputs, deps: [], target: i0.ɵɵFactoryTarget.Directive });
62
+ WklyPickerInputs.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: WklyPickerInputs, inputs: { mode: "mode", value: "value", calendarAdapter: "calendarAdapter", locale: "locale", weekOffset: "weekOffset", viewportPreset: "viewportPreset", hourCycle: "hourCycle", showSeconds: "showSeconds", minuteStep: "minuteStep", secondStep: "secondStep", min: "min", max: "max", isDateDisabled: "isDateDisabled", isTimeDisabled: "isTimeDisabled", rangeValidator: "rangeValidator", allowRangeAcrossDisabled: "allowRangeAcrossDisabled", required: "required", disabled: "disabled", weekLabelMode: "weekLabelMode", weekLabelFormatter: "weekLabelFormatter", weekCacheSize: "weekCacheSize", overscanWeeks: "overscanWeeks", ariaLabel: "ariaLabel", ariaDescribedBy: "ariaDescribedBy", initialEpochDay: "initialEpochDay", closeOnBackdrop: "closeOnBackdrop", validators: "validators", translations: "translations" }, outputs: { valueChange: "valueChange", validationChange: "validationChange", opened: "opened", closed: "closed", viewportChange: "viewportChange", viewModeChange: "viewModeChange" }, ngImport: i0 });
63
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyPickerInputs, decorators: [{
64
+ type: Directive,
65
+ args: [{
66
+ inputs: [
67
+ "mode",
68
+ "value",
69
+ "calendarAdapter",
70
+ "locale",
71
+ "weekOffset",
72
+ "viewportPreset",
73
+ "hourCycle",
74
+ "showSeconds",
75
+ "minuteStep",
76
+ "secondStep",
77
+ "min",
78
+ "max",
79
+ "isDateDisabled",
80
+ "isTimeDisabled",
81
+ "rangeValidator",
82
+ "allowRangeAcrossDisabled",
83
+ "required",
84
+ "disabled",
85
+ "weekLabelMode",
86
+ "weekLabelFormatter",
87
+ "weekCacheSize",
88
+ "overscanWeeks",
89
+ "ariaLabel",
90
+ "ariaDescribedBy",
91
+ "initialEpochDay",
92
+ "closeOnBackdrop",
93
+ "validators",
94
+ "translations",
95
+ ],
96
+ outputs: [
97
+ "valueChange",
98
+ "validationChange",
99
+ "opened",
100
+ "closed",
101
+ "viewportChange",
102
+ "viewModeChange",
103
+ ],
104
+ }]
105
+ }] });
106
+
107
+ class WklyFieldComponent {
108
+ constructor() {
109
+ this.value = 0;
110
+ this.label = "";
111
+ this.hideLabel = false;
112
+ this.previousLabel = "";
113
+ this.nextLabel = "";
114
+ this.min = 0;
115
+ this.max = 59;
116
+ this.step = 1;
117
+ this.locale = "en-US";
118
+ this.disabled = false;
119
+ this.invalid = false;
120
+ this.labels = null;
121
+ this.valueChange = new EventEmitter();
122
+ this.complete = new EventEmitter();
123
+ this.before = null;
124
+ this.touchY = 0;
125
+ this.touchSteps = 0;
126
+ this.touchChanged = false;
127
+ this.typed = null;
128
+ this.inputTimer = null;
129
+ this.wheelTimer = null;
130
+ }
131
+ get display() {
132
+ if (this.typed !== null)
133
+ return this.typed;
134
+ return this.value === null
135
+ ? ""
136
+ : this.labels
137
+ ? this.labels[this.value - this.min] || String(this.value)
138
+ : new Intl.NumberFormat(this.locale, {
139
+ useGrouping: false,
140
+ minimumIntegerDigits: this.max < 60 ? 2 : 1,
141
+ }).format(this.value);
142
+ }
143
+ ngOnChanges(changes) {
144
+ if (changes.value && this.min < 0 && this.typed !== null) {
145
+ const typedValue = this.typed === "" || this.typed === "-" ? null : Number(this.typed);
146
+ if (this.value !== typedValue) {
147
+ // External date edits replace a pending relative-day preview.
148
+ this.cancelInput();
149
+ this.typed = null;
150
+ }
151
+ }
152
+ }
153
+ ngOnDestroy() {
154
+ this.cancelInput();
155
+ if (this.wheelTimer !== null)
156
+ clearTimeout(this.wheelTimer);
157
+ }
158
+ next(delta) {
159
+ const count = Math.floor((this.max - this.min) / this.step) + 1;
160
+ return (this.min +
161
+ floorMod(Math.floor(((this.value === null ? this.min : this.value) - this.min) /
162
+ this.step) + delta, count) *
163
+ this.step);
164
+ }
165
+ neighbor(delta) {
166
+ const n = this.next(delta);
167
+ return this.labels
168
+ ? this.labels[n - this.min] || ""
169
+ : new Intl.NumberFormat(this.locale, { useGrouping: false }).format(n);
170
+ }
171
+ stepBy(delta) {
172
+ if (this.disabled)
173
+ return;
174
+ this.scrollBy(delta);
175
+ this.complete.emit();
176
+ }
177
+ begin(event) {
178
+ this.before = this.value;
179
+ event.target.select();
180
+ }
181
+ type(event) {
182
+ if (this.disabled)
183
+ return;
184
+ const input = event.target;
185
+ const raw = input.value;
186
+ const numeric = Array.from(raw).every((character) => normalizeDigits(character).length === 1);
187
+ if (this.min < 0 && !this.labels) {
188
+ // Preserve the sign while using the same locale digit normalization.
189
+ const signed = raw
190
+ .replace(/[\u200e\u200f\u061c]/g, "")
191
+ .replace(/\u2212/g, "-");
192
+ const digits = normalizeDigits(signed);
193
+ this.typed = input.value = (signed.startsWith("-") ? "-" : "") + digits;
194
+ this.value =
195
+ digits === ""
196
+ ? null
197
+ : Math.max(this.min, Math.min(this.max, Number(this.typed)));
198
+ if (this.value !== null && Number(this.typed) !== this.value)
199
+ this.typed = input.value = String(this.value);
200
+ }
201
+ else if (numeric) {
202
+ const normalized = normalizeDigits(raw);
203
+ this.typed = input.value =
204
+ this.min >= 0 && this.max < 100 ? normalized.slice(-2) : normalized;
205
+ this.value = this.typed === "" ? null : Number(this.typed);
206
+ }
207
+ else if (this.labels) {
208
+ const search = raw.trim().toLocaleLowerCase(this.locale);
209
+ this.typed = raw;
210
+ const matches = this.labels
211
+ .map((label, index) => ({ label, index }))
212
+ .filter((item) => item.label.toLocaleLowerCase(this.locale).includes(search));
213
+ this.value = matches.length === 1 ? this.min + matches[0].index : null;
214
+ }
215
+ else {
216
+ this.typed = input.value = normalizeDigits(raw);
217
+ this.value = this.typed === "" ? null : Number(this.typed);
218
+ }
219
+ this.valueChange.emit(this.value);
220
+ this.cancelInput();
221
+ if (!numeric && this.labels && this.value !== null)
222
+ this.complete.emit();
223
+ this.inputTimer = setTimeout(() => {
224
+ this.inputTimer = null;
225
+ this.typed = null;
226
+ if (!this.disabled)
227
+ this.complete.emit();
228
+ }, 1000);
229
+ }
230
+ key(event) {
231
+ if (event.key === "Escape") {
232
+ event.preventDefault();
233
+ event.stopPropagation();
234
+ this.cancelInput();
235
+ this.typed = null;
236
+ this.value = this.before;
237
+ this.valueChange.emit(this.before);
238
+ event.target.value = this.display;
239
+ event.target.blur();
240
+ }
241
+ if (event.key === "Enter") {
242
+ event.preventDefault();
243
+ event.stopPropagation();
244
+ this.finish();
245
+ }
246
+ const delta = event.key === "ArrowUp"
247
+ ? -1
248
+ : event.key === "ArrowDown"
249
+ ? 1
250
+ : event.key === "PageUp"
251
+ ? -5
252
+ : event.key === "PageDown"
253
+ ? 5
254
+ : 0;
255
+ if (delta) {
256
+ event.preventDefault();
257
+ this.stepBy(delta);
258
+ }
259
+ }
260
+ finish() {
261
+ this.cancelInput();
262
+ this.typed = null;
263
+ this.complete.emit();
264
+ }
265
+ wheel(event) {
266
+ if (this.disabled || Math.abs(event.deltaY) < 1)
267
+ return;
268
+ event.preventDefault();
269
+ this.scrollBy(event.deltaY > 0 ? 1 : -1);
270
+ if (this.wheelTimer !== null)
271
+ clearTimeout(this.wheelTimer);
272
+ this.wheelTimer = setTimeout(() => {
273
+ this.wheelTimer = null;
274
+ this.complete.emit();
275
+ }, 140);
276
+ }
277
+ touchStart(event) {
278
+ this.touchY = event.touches[0].clientY;
279
+ this.touchSteps = 0;
280
+ this.touchChanged = false;
281
+ }
282
+ touchMove(event) {
283
+ this.applyTouchY(event.touches[0].clientY);
284
+ }
285
+ touchEnd(event) {
286
+ this.applyTouchY(event.changedTouches[0].clientY);
287
+ if (this.touchChanged)
288
+ this.complete.emit();
289
+ this.touchChanged = false;
290
+ }
291
+ cancelInput() {
292
+ if (this.inputTimer !== null)
293
+ clearTimeout(this.inputTimer);
294
+ this.inputTimer = null;
295
+ }
296
+ scrollBy(delta) {
297
+ if (this.disabled || !delta)
298
+ return;
299
+ this.cancelInput();
300
+ this.typed = null;
301
+ this.value = this.next(delta);
302
+ this.valueChange.emit(this.value);
303
+ }
304
+ applyTouchY(y) {
305
+ // Count total gesture steps so repeated move events do not duplicate changes.
306
+ if (this.disabled)
307
+ return;
308
+ const delta = this.touchY - y;
309
+ const steps = Math.abs(delta) > 16
310
+ ? Math.sign(delta) * Math.max(1, Math.round(Math.abs(delta) / 40))
311
+ : 0;
312
+ const change = steps - this.touchSteps;
313
+ if (!change)
314
+ return;
315
+ this.scrollBy(change);
316
+ this.touchSteps = steps;
317
+ this.touchChanged = true;
318
+ }
319
+ }
320
+ WklyFieldComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
321
+ WklyFieldComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: WklyFieldComponent, selector: "wkly-field", inputs: { value: "value", label: "label", hideLabel: "hideLabel", previousLabel: "previousLabel", nextLabel: "nextLabel", min: "min", max: "max", step: "step", locale: "locale", disabled: "disabled", invalid: "invalid", labels: "labels" }, outputs: { valueChange: "valueChange", complete: "complete" }, usesOnChanges: true, ngImport: i0, template: "<div\n class=\"field\"\n (wheel)=\"wheel($event)\"\n (touchstart)=\"touchStart($event)\"\n (touchmove)=\"touchMove($event)\"\n (touchend)=\"touchEnd($event)\"\n (touchcancel)=\"touchEnd($event)\"\n>\n <span *ngIf=\"!hideLabel\" class=\"label\">{{ label }}</span>\n <button\n type=\"button\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"previousLabel || label + ': previous'\"\n (click)=\"stepBy(-1)\"\n >\n {{ neighbor(-1) }}\n </button>\n <input\n [attr.aria-label]=\"label\"\n [attr.aria-invalid]=\"invalid\"\n [disabled]=\"disabled\"\n [value]=\"display\"\n [attr.inputmode]=\"labels ? 'text' : min < 0 ? 'text' : 'numeric'\"\n autocomplete=\"off\"\n (focus)=\"begin($event)\"\n (input)=\"type($event)\"\n (blur)=\"finish()\"\n (keydown)=\"key($event)\"\n />\n <button\n type=\"button\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"nextLabel || label + ': next'\"\n (click)=\"stepBy(1)\"\n >\n {{ neighbor(1) }}\n </button>\n</div>\n", styles: [".field{display:flex;flex-direction:column;align-items:stretch;min-width:0;text-align:center;touch-action:pan-x}.label{font-size:11px;color:var(--wkly-muted-color, #54616e);margin-bottom:4px}button,input{font:inherit;box-sizing:border-box;min-height:44px;width:100%;border:0;text-align:center;background:transparent;color:inherit;border-radius:7px}button{color:var(--wkly-muted-color, #54616e);cursor:pointer}input{font-size:18px;font-weight:650;background:var(--wkly-range-color, #e5f1ee);border-block:2px solid var(--wkly-accent-color, #176c55)}input[aria-invalid=true]{border-color:var(--wkly-error-color, #b42318)}:focus-visible{outline:2px solid var(--wkly-focus-color, #124ee0);outline-offset:1px}button:disabled,input:disabled{opacity:.45}button:hover:not(:disabled){background:var(--wkly-range-color, #e5f1ee)}\n"], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
322
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyFieldComponent, decorators: [{
323
+ type: Component,
324
+ args: [{ selector: "wkly-field", template: "<div\n class=\"field\"\n (wheel)=\"wheel($event)\"\n (touchstart)=\"touchStart($event)\"\n (touchmove)=\"touchMove($event)\"\n (touchend)=\"touchEnd($event)\"\n (touchcancel)=\"touchEnd($event)\"\n>\n <span *ngIf=\"!hideLabel\" class=\"label\">{{ label }}</span>\n <button\n type=\"button\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"previousLabel || label + ': previous'\"\n (click)=\"stepBy(-1)\"\n >\n {{ neighbor(-1) }}\n </button>\n <input\n [attr.aria-label]=\"label\"\n [attr.aria-invalid]=\"invalid\"\n [disabled]=\"disabled\"\n [value]=\"display\"\n [attr.inputmode]=\"labels ? 'text' : min < 0 ? 'text' : 'numeric'\"\n autocomplete=\"off\"\n (focus)=\"begin($event)\"\n (input)=\"type($event)\"\n (blur)=\"finish()\"\n (keydown)=\"key($event)\"\n />\n <button\n type=\"button\"\n [disabled]=\"disabled\"\n [attr.aria-label]=\"nextLabel || label + ': next'\"\n (click)=\"stepBy(1)\"\n >\n {{ neighbor(1) }}\n </button>\n</div>\n", styles: [".field{display:flex;flex-direction:column;align-items:stretch;min-width:0;text-align:center;touch-action:pan-x}.label{font-size:11px;color:var(--wkly-muted-color, #54616e);margin-bottom:4px}button,input{font:inherit;box-sizing:border-box;min-height:44px;width:100%;border:0;text-align:center;background:transparent;color:inherit;border-radius:7px}button{color:var(--wkly-muted-color, #54616e);cursor:pointer}input{font-size:18px;font-weight:650;background:var(--wkly-range-color, #e5f1ee);border-block:2px solid var(--wkly-accent-color, #176c55)}input[aria-invalid=true]{border-color:var(--wkly-error-color, #b42318)}:focus-visible{outline:2px solid var(--wkly-focus-color, #124ee0);outline-offset:1px}button:disabled,input:disabled{opacity:.45}button:hover:not(:disabled){background:var(--wkly-range-color, #e5f1ee)}\n"] }]
325
+ }], propDecorators: { value: [{
326
+ type: Input
327
+ }], label: [{
328
+ type: Input
329
+ }], hideLabel: [{
330
+ type: Input
331
+ }], previousLabel: [{
332
+ type: Input
333
+ }], nextLabel: [{
334
+ type: Input
335
+ }], min: [{
336
+ type: Input
337
+ }], max: [{
338
+ type: Input
339
+ }], step: [{
340
+ type: Input
341
+ }], locale: [{
342
+ type: Input
343
+ }], disabled: [{
344
+ type: Input
345
+ }], invalid: [{
346
+ type: Input
347
+ }], labels: [{
348
+ type: Input
349
+ }], valueChange: [{
350
+ type: Output
351
+ }], complete: [{
352
+ type: Output
353
+ }] } });
354
+
355
+ class WklyDateTimePickerComponent extends WklyPickerInputs {
356
+ constructor(defaultLocale, defaults, clock, strings, defaultTranslations, platform, host, changeDetector) {
357
+ super();
358
+ this.defaultLocale = defaultLocale;
359
+ this.defaults = defaults;
360
+ this.clock = clock;
361
+ this.strings = strings;
362
+ this.defaultTranslations = defaultTranslations;
363
+ this.host = host;
364
+ this.changeDetector = changeDetector;
365
+ this.presentation = "inline";
366
+ this.viewMode = "calendar";
367
+ this.endView = "date";
368
+ this.effectiveLocale = "en-US";
369
+ this.effectiveOffset = 0;
370
+ this.effectiveHourCycle = "h24";
371
+ this.direction = "ltr";
372
+ this.rows = [];
373
+ this.weekdays = [];
374
+ this.drafts = [];
375
+ this.errors = [];
376
+ this.today = 0;
377
+ this.focused = 0;
378
+ this.anchorWeek = 0;
379
+ this.firstWeek = 0;
380
+ this.visibleCount = 6;
381
+ this.rowHeight = 76;
382
+ this.scrollHeight = 152076;
383
+ this.paddingTop = 0;
384
+ this.initialized = false;
385
+ this.compact = false;
386
+ this.WklyPickerInputsPropertyKeys = WklyPickerInputsPropertyKeys;
387
+ this.baseWeek = 0;
388
+ this.firstSupportedDay = 0;
389
+ this.lastSupportedDay = 0;
390
+ this.firstSupportedWeek = 0;
391
+ this.lastSupportedWeek = 0;
392
+ this.initialMonth = "";
393
+ this.clipMonth = false;
394
+ this.browser = false;
395
+ this.destroyed = false;
396
+ this.snapPending = false;
397
+ this.onChange = () => { };
398
+ this.onTouched = () => { };
399
+ this.validatorChanged = () => { };
400
+ this.configErrors = [];
401
+ this.pendingValue = null;
402
+ this.emittedValue = null;
403
+ this.manualDateEndpoint = 0;
404
+ this.browser = isPlatformBrowser(platform);
405
+ }
406
+ ngOnInit() {
407
+ this.initialize();
408
+ }
409
+ ngOnChanges(changes) {
410
+ if (this.initialized) {
411
+ if (Object.keys(changes).length === 1 &&
412
+ changes[WklyPickerInputsPropertyKeys.Value] &&
413
+ this.emittedValue ===
414
+ JSON.stringify(this[WklyPickerInputsPropertyKeys.Value])) {
415
+ this.emittedValue = null;
416
+ return;
417
+ }
418
+ const focus = this.focused;
419
+ this.configure();
420
+ if (changes[WklyPickerInputsPropertyKeys.Value] ||
421
+ changes[WklyPickerInputsPropertyKeys.Mode] ||
422
+ changes[WklyPickerInputsPropertyKeys.CalendarAdapter]) {
423
+ this.load(this[WklyPickerInputsPropertyKeys.Value]);
424
+ this.position(this.focused, true);
425
+ }
426
+ else {
427
+ this.check();
428
+ if (changes[WklyPickerInputsPropertyKeys.ViewportPreset])
429
+ this.position(focus, true);
430
+ else
431
+ this.scrollToEpochDay(focus);
432
+ }
433
+ }
434
+ }
435
+ initialize() {
436
+ if (this.initialized)
437
+ return;
438
+ this.configure();
439
+ const initialEpochDay = this[WklyPickerInputsPropertyKeys.InitialEpochDay];
440
+ this.today = this.browser
441
+ ? Math.floor(this.clock.now().getTime() / 86400000)
442
+ : initialEpochDay === null
443
+ ? 0
444
+ : initialEpochDay;
445
+ this.focused =
446
+ initialEpochDay === null
447
+ ? this.defaults.initialEpochDay === undefined
448
+ ? this.today
449
+ : this.defaults.initialEpochDay
450
+ : initialEpochDay;
451
+ this.load(this[WklyPickerInputsPropertyKeys.Value]);
452
+ this.initialized = true;
453
+ this.position(this.focused, true);
454
+ }
455
+ configure() {
456
+ this.configErrors = [];
457
+ [
458
+ WklyPickerInputsPropertyKeys.ShowSeconds,
459
+ WklyPickerInputsPropertyKeys.AllowRangeAcrossDisabled,
460
+ WklyPickerInputsPropertyKeys.Required,
461
+ WklyPickerInputsPropertyKeys.Disabled,
462
+ WklyPickerInputsPropertyKeys.CloseOnBackdrop,
463
+ ].forEach((key) => (this[key] = coerceBoolean(this[key])));
464
+ this.effectiveLocale =
465
+ this[WklyPickerInputsPropertyKeys.Locale] ||
466
+ this.defaults.locale ||
467
+ this.defaultLocale;
468
+ this.direction = /^(ar|he|fa|ur)(-|$)/.test(this.effectiveLocale)
469
+ ? "rtl"
470
+ : "ltr";
471
+ this.adapter =
472
+ this[WklyPickerInputsPropertyKeys.CalendarAdapter] ||
473
+ new WklyGregorianCalendarAdapter(this.effectiveLocale);
474
+ try {
475
+ let firstDay;
476
+ try {
477
+ firstDay = getLocaleFirstDayOfWeek(this.effectiveLocale);
478
+ }
479
+ catch (_) { }
480
+ this.effectiveOffset = resolveWeekOffset(this.effectiveLocale, this[WklyPickerInputsPropertyKeys.WeekOffset], this.defaults.weekOffset, firstDay);
481
+ integer(this[WklyPickerInputsPropertyKeys.WeekCacheSize]);
482
+ integer(this[WklyPickerInputsPropertyKeys.OverscanWeeks]);
483
+ if (this[WklyPickerInputsPropertyKeys.WeekCacheSize] < 0 ||
484
+ this[WklyPickerInputsPropertyKeys.OverscanWeeks] < 0 ||
485
+ this[WklyPickerInputsPropertyKeys.OverscanWeeks] > 50)
486
+ throw new RangeError();
487
+ if (![
488
+ "datetime",
489
+ "date",
490
+ "time",
491
+ "datetime-range",
492
+ "date-range",
493
+ "time-range",
494
+ ].includes(this[WklyPickerInputsPropertyKeys.Mode]))
495
+ throw new RangeError();
496
+ const preset = this[WklyPickerInputsPropertyKeys.ViewportPreset];
497
+ if (preset.kind === "weeks") {
498
+ integer(preset.visibleWeekCount);
499
+ if (preset.visibleWeekCount < 1 || preset.visibleWeekCount > 52)
500
+ throw new RangeError();
501
+ }
502
+ if (preset.kind === "full-month-and-around")
503
+ for (const n of [
504
+ preset.extraWeeksBefore || 0,
505
+ preset.extraWeeksAfter || 0,
506
+ ]) {
507
+ integer(n);
508
+ if (n < 0 || n > 52)
509
+ throw new RangeError();
510
+ }
511
+ this.generator = createWeekGenerator({
512
+ weekOffset: this.effectiveOffset,
513
+ cacheSize: this[WklyPickerInputsPropertyKeys.WeekCacheSize],
514
+ });
515
+ }
516
+ catch (_) {
517
+ this.configErrors.push(error("configuration-error", this[WklyPickerInputsPropertyKeys.WeekOffset]));
518
+ this.generator = createWeekGenerator();
519
+ this.effectiveOffset = 0;
520
+ }
521
+ this.setSupportedScrollRange();
522
+ this.effectiveHourCycle =
523
+ this[WklyPickerInputsPropertyKeys.HourCycle] === "h12"
524
+ ? "h12"
525
+ : this[WklyPickerInputsPropertyKeys.HourCycle] === "locale"
526
+ ? new Intl.DateTimeFormat(this.effectiveLocale, {
527
+ hour: "numeric",
528
+ timeZone: "UTC",
529
+ }).resolvedOptions().hour12
530
+ ? "h12"
531
+ : "h24"
532
+ : "h24";
533
+ this.weekdays = Array.from({ length: 7 }, (_, i) => this.adapter.formatWeekday(this.effectiveOffset + i, "short"));
534
+ }
535
+ setSupportedScrollRange() {
536
+ let [first, last] = this.adapter.supportedEpochDayRange;
537
+ const [firstYear, lastYear] = this.adapter.supportedYearRange;
538
+ const yearOf = (day) => this.adapter.epochDayToDate(day).year;
539
+ if (yearOf(first) < firstYear) {
540
+ let low = first, high = last;
541
+ while (low < high) {
542
+ const mid = Math.floor((low + high) / 2);
543
+ if (yearOf(mid) < firstYear)
544
+ low = mid + 1;
545
+ else
546
+ high = mid;
547
+ }
548
+ first = low;
549
+ }
550
+ if (yearOf(last) > lastYear) {
551
+ let low = first, high = last;
552
+ while (low < high) {
553
+ const mid = Math.ceil((low + high) / 2);
554
+ if (yearOf(mid) > lastYear)
555
+ high = mid - 1;
556
+ else
557
+ low = mid;
558
+ }
559
+ last = low;
560
+ }
561
+ if (first > last ||
562
+ yearOf(first) < firstYear ||
563
+ yearOf(first) > lastYear ||
564
+ yearOf(last) < firstYear ||
565
+ yearOf(last) > lastYear)
566
+ throw new RangeError("No supported days within the calendar year range");
567
+ this.firstSupportedDay = first;
568
+ this.lastSupportedDay = last;
569
+ this.firstSupportedWeek = absoluteWeekOf(first, this.effectiveOffset);
570
+ this.lastSupportedWeek = absoluteWeekOf(last, this.effectiveOffset);
571
+ }
572
+ clampFirstWeek(week) {
573
+ // Keep supported weeks inside the viewport; renderRows adds the buffer rows.
574
+ const last = Math.max(this.firstSupportedWeek, this.lastSupportedWeek - this.visibleCount + 1);
575
+ return Math.max(this.firstSupportedWeek, Math.min(last, week));
576
+ }
577
+ ngAfterViewInit() {
578
+ this.resetScroll();
579
+ if (this.browser && typeof ResizeObserver !== "undefined") {
580
+ this.observer = new ResizeObserver(() => {
581
+ this.compact = this.host.nativeElement.clientWidth < 338;
582
+ const row = this.host.nativeElement.querySelector(".week-row");
583
+ // CSS heights and scrollTop use layout pixels; client rectangles include zoom.
584
+ const height = row ? parseFloat(getComputedStyle(row).height) : 0;
585
+ if (height && height !== this.rowHeight) {
586
+ this.rowHeight = height;
587
+ this.scrollHeight = this.rowHeight * 2001;
588
+ this.renderRows();
589
+ this.resetScroll();
590
+ }
591
+ });
592
+ this.observer.observe(this.host.nativeElement);
593
+ }
594
+ }
595
+ ngOnDestroy() {
596
+ this.destroyed = true;
597
+ if (this.observer)
598
+ this.observer.disconnect();
599
+ if (this.scrollEndTimer)
600
+ clearTimeout(this.scrollEndTimer);
601
+ if (this.generator)
602
+ this.generator.clearCache();
603
+ }
604
+ t(key) {
605
+ return resolveWklyTranslation(key, this.effectiveLocale, this[WklyPickerInputsPropertyKeys.Translations] ||
606
+ this.defaultTranslations, this.strings);
607
+ }
608
+ get isRange() {
609
+ return this[WklyPickerInputsPropertyKeys.Mode].endsWith("-range");
610
+ }
611
+ get hasDate() {
612
+ return !this[WklyPickerInputsPropertyKeys.Mode].startsWith("time");
613
+ }
614
+ get hasTime() {
615
+ return (this[WklyPickerInputsPropertyKeys.Mode] !== "date" &&
616
+ this[WklyPickerInputsPropertyKeys.Mode] !== "date-range");
617
+ }
618
+ get submitVisible() {
619
+ return (this.presentation === "transient" &&
620
+ (this[WklyPickerInputsPropertyKeys.Mode] !== "date" ||
621
+ this.viewMode === "manual"));
622
+ }
623
+ get title() {
624
+ try {
625
+ const d = this.adapter.epochDayToDate(Math.max(this.firstSupportedDay, Math.min(this.lastSupportedDay, firstEpochDayOf(this.anchorWeek, this.effectiveOffset))));
626
+ return this.adapter.formatMonth(d) + " " + this.adapter.formatYear(d);
627
+ }
628
+ catch (_) {
629
+ return "";
630
+ }
631
+ }
632
+ get canSubmit() {
633
+ return (!this[WklyPickerInputsPropertyKeys.Disabled] &&
634
+ !this.errors.length &&
635
+ this.pendingValue !== null);
636
+ }
637
+ blank(day) {
638
+ const safe = Math.max(this.firstSupportedDay, Math.min(this.lastSupportedDay, day));
639
+ return {
640
+ date: this.adapter.epochDayToDate(safe),
641
+ hour: 0,
642
+ minute: 0,
643
+ second: 0,
644
+ present: false,
645
+ };
646
+ }
647
+ load(value) {
648
+ this.drafts = [this.blank(this.focused), this.blank(this.focused)];
649
+ const validation = validateSelection(value, this, this.adapter);
650
+ if (value !== null && !validation.length) {
651
+ const values = typeof value === "string" ? [value] : value;
652
+ values.forEach((v, i) => {
653
+ const d = decodeIso(v);
654
+ this.drafts[i] = {
655
+ date: this.hasDate
656
+ ? this.adapter.epochDayToDate(d.epochDay)
657
+ : this.blank(this.today).date,
658
+ hour: d.hour,
659
+ minute: d.minute,
660
+ second: d.second,
661
+ present: true,
662
+ };
663
+ if (i === 0 && this.hasDate)
664
+ this.focused = d.epochDay;
665
+ });
666
+ }
667
+ if (validation.length) {
668
+ this.pendingValue = null;
669
+ this.report(validation);
670
+ }
671
+ else
672
+ this.check();
673
+ }
674
+ writeValue(value) {
675
+ this[WklyPickerInputsPropertyKeys.Value] = value;
676
+ if (this.initialized) {
677
+ this.load(value);
678
+ this.position(this.focused, true);
679
+ }
680
+ }
681
+ registerOnChange(fn) {
682
+ this.onChange = fn;
683
+ }
684
+ registerOnTouched(fn) {
685
+ this.onTouched = fn;
686
+ }
687
+ setDisabledState(disabled) {
688
+ this[WklyPickerInputsPropertyKeys.Disabled] = disabled;
689
+ }
690
+ validate(_control) {
691
+ return this.errors.length ? { wkly: this.errors } : null;
692
+ }
693
+ registerOnValidatorChange(fn) {
694
+ this.validatorChanged = fn;
695
+ }
696
+ touched() {
697
+ Promise.resolve().then(() => this.onTouched());
698
+ }
699
+ report(errors) {
700
+ const changed = JSON.stringify(this.errors) !== JSON.stringify(errors);
701
+ this.errors = errors;
702
+ if (changed) {
703
+ this[WklyPickerOutputsPropertyKeys.ValidationChange].emit(errors);
704
+ this.validatorChanged();
705
+ }
706
+ }
707
+ check() {
708
+ const result = validateDrafts({
709
+ drafts: this.drafts,
710
+ configErrors: this.configErrors,
711
+ adapter: this.adapter,
712
+ selection: this,
713
+ mode: this[WklyPickerInputsPropertyKeys.Mode],
714
+ isRange: this.isRange,
715
+ hasDate: this.hasDate,
716
+ hasTime: this.hasTime,
717
+ showSeconds: this[WklyPickerInputsPropertyKeys.ShowSeconds],
718
+ required: this[WklyPickerInputsPropertyKeys.Required],
719
+ });
720
+ this.pendingValue = result.pendingValue;
721
+ this.report(result.errors);
722
+ }
723
+ trackDraft(index) {
724
+ // Endpoint controls keep their identity and focus when draft objects swap.
725
+ return index;
726
+ }
727
+ orderDrafts() {
728
+ if (!this.isRange || !this.drafts.every((draft) => draft.present))
729
+ return;
730
+ if (this.drafts.some((draft) => draft.unsupportedEpochDay !== undefined))
731
+ return;
732
+ try {
733
+ const a = this.drafts[0], b = this.drafts[1];
734
+ const key = (d) => this.adapter.dateToEpochDay(d.date) * 86400 +
735
+ (d.hour || 0) * 3600 +
736
+ (d.minute || 0) * 60 +
737
+ (d.second || 0);
738
+ if (key(a) > key(b))
739
+ this.drafts = [b, a];
740
+ }
741
+ catch (_) {
742
+ // Impossible or incomplete dates remain editable until corrected.
743
+ }
744
+ }
745
+ finish() {
746
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
747
+ return;
748
+ this.orderDrafts();
749
+ if (this.viewMode === "manual" && this.hasDate)
750
+ this.positionOnManualDate();
751
+ this.check();
752
+ if (this.presentation === "inline" && this.canSubmit)
753
+ this.commit();
754
+ }
755
+ commit() {
756
+ if (!this.canSubmit)
757
+ return;
758
+ const next = this.pendingValue;
759
+ if (JSON.stringify(next) !==
760
+ JSON.stringify(this[WklyPickerInputsPropertyKeys.Value])) {
761
+ this[WklyPickerInputsPropertyKeys.Value] = next;
762
+ this.emittedValue = JSON.stringify(next);
763
+ this.onChange(next);
764
+ this[WklyPickerOutputsPropertyKeys.ValueChange].emit(next);
765
+ }
766
+ this.onTouched();
767
+ }
768
+ submit(reason = "submit") {
769
+ this.check();
770
+ if (!this.canSubmit)
771
+ return;
772
+ this.commit();
773
+ if (this.presentation === "transient")
774
+ this[WklyPickerOutputsPropertyKeys.Closed].emit(reason);
775
+ }
776
+ cancel(reason = "close-button") {
777
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
778
+ return;
779
+ this.load(this[WklyPickerInputsPropertyKeys.Value]);
780
+ this.onTouched();
781
+ this[WklyPickerOutputsPropertyKeys.Closed].emit(reason);
782
+ }
783
+ now() {
784
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
785
+ return;
786
+ const n = this.clock.now();
787
+ const day = Math.floor(n.getTime() / 86400000);
788
+ this.drafts = [0, 1].map((index) => ({
789
+ ...this.clockDraft(day, n),
790
+ present: index === 0 || this.isRange,
791
+ }));
792
+ if (this.hasDate &&
793
+ (day < this.firstSupportedDay || day > this.lastSupportedDay)) {
794
+ this.report([error("unsupported-adapter-date", day)]);
795
+ return;
796
+ }
797
+ this.focused = day;
798
+ this.position(day, true);
799
+ this.check();
800
+ this.submit("now");
801
+ }
802
+ clockDraft(day, now) {
803
+ return {
804
+ ...this.blank(day),
805
+ hour: now.getUTCHours(),
806
+ minute: Math.floor(now.getUTCMinutes() / this[WklyPickerInputsPropertyKeys.MinuteStep]) * this[WklyPickerInputsPropertyKeys.MinuteStep],
807
+ second: this[WklyPickerInputsPropertyKeys.ShowSeconds]
808
+ ? Math.floor(now.getUTCSeconds() / this[WklyPickerInputsPropertyKeys.SecondStep]) * this[WklyPickerInputsPropertyKeys.SecondStep]
809
+ : 0,
810
+ };
811
+ }
812
+ initializeManualRange() {
813
+ if (!this.isRange ||
814
+ !this.hasDate ||
815
+ this.drafts.every((draft) => draft.present))
816
+ return;
817
+ let seed = this.drafts.find((draft) => draft.present);
818
+ if (!seed) {
819
+ if (this[WklyPickerInputsPropertyKeys.Value] !== null)
820
+ return;
821
+ const now = this.clock.now();
822
+ const initialEpochDay = this[WklyPickerInputsPropertyKeys.InitialEpochDay];
823
+ const day = initialEpochDay === null
824
+ ? this.defaults.initialEpochDay === undefined
825
+ ? Math.floor(now.getTime() / 86400000)
826
+ : this.defaults.initialEpochDay
827
+ : initialEpochDay;
828
+ seed = { ...this.clockDraft(day, now), present: true };
829
+ }
830
+ // Complete missing endpoints without replacing selected or invalid drafts.
831
+ const initial = seed;
832
+ this.drafts = this.drafts.map((draft) => draft.present ? draft : { ...initial, date: { ...initial.date } });
833
+ this.finish();
834
+ // Positioning renders before validation; refresh completion controls afterward.
835
+ this.changeDetector.markForCheck();
836
+ }
837
+ toggleView() {
838
+ if (this[WklyPickerInputsPropertyKeys.Disabled] || !this.hasDate)
839
+ return;
840
+ this.viewMode = this.viewMode === "calendar" ? "manual" : "calendar";
841
+ if (this.viewMode === "manual")
842
+ this.initializeManualRange();
843
+ if (this.viewMode === "calendar")
844
+ this.positionOnManualDate();
845
+ this[WklyPickerOutputsPropertyKeys.ViewModeChange].emit(this.viewMode);
846
+ if (this.viewMode === "calendar")
847
+ setTimeout(() => this.resetScroll());
848
+ }
849
+ positionOnManualDate() {
850
+ const draft = this.drafts[this.manualDateEndpoint];
851
+ if (!draft || !draft.present)
852
+ return;
853
+ try {
854
+ // A valid day follows the selection. An impossible day keeps its draft
855
+ // fields but still shows the chosen month in the calendar.
856
+ const target = this.adapter.dateToEpochDay(draft.date);
857
+ this.focused = target;
858
+ this.position(target, true);
859
+ }
860
+ catch (_) {
861
+ try {
862
+ const first = this.adapter.dateToEpochDay({ ...draft.date, day: 1 });
863
+ this.focused = first;
864
+ this.position(first, true);
865
+ }
866
+ catch (_) { }
867
+ }
868
+ }
869
+ months(draft) {
870
+ try {
871
+ return this.adapter.getMonths(draft.date.year).map((m) => m.label);
872
+ }
873
+ catch (_) {
874
+ return [];
875
+ }
876
+ }
877
+ monthCount(draft) {
878
+ return this.months(draft).length || 12;
879
+ }
880
+ get inDays() {
881
+ return draftDayDifference(this.drafts, this.adapter);
882
+ }
883
+ get inDaysLabel() {
884
+ const days = this.inDays;
885
+ return this.t("inDays").replace(/{{\s*days\s*}}/g, days === null
886
+ ? this.t("daysUnavailable")
887
+ : new Intl.NumberFormat(this.effectiveLocale, {
888
+ useGrouping: false,
889
+ }).format(days));
890
+ }
891
+ get resultingEndDate() {
892
+ try {
893
+ const draft = this.drafts[1];
894
+ if (draft.unsupportedEpochDay !== undefined ||
895
+ this.adapter.validateDate(draft.date).length)
896
+ return "";
897
+ return [
898
+ this.adapter.formatDay(draft.date),
899
+ this.adapter.formatMonth(draft.date),
900
+ this.adapter.formatYear(draft.date),
901
+ ].join(" ");
902
+ }
903
+ catch (_) {
904
+ return "";
905
+ }
906
+ }
907
+ toggleEndView(view) {
908
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
909
+ return;
910
+ this.endView = view;
911
+ }
912
+ days(value) {
913
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
914
+ return;
915
+ this.manualDateEndpoint = 1;
916
+ setDraftDayDifference(this.drafts, this.adapter, value);
917
+ this.check();
918
+ }
919
+ field(index, field, value) {
920
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
921
+ return;
922
+ const draft = this.drafts[index];
923
+ draft.present = true;
924
+ if (field === "day" || field === "year" || field === "month") {
925
+ this.manualDateEndpoint = index;
926
+ delete draft.unsupportedEpochDay;
927
+ let date = { ...draft.date, [field]: value };
928
+ if (field === "month") {
929
+ let month;
930
+ try {
931
+ month = this.adapter
932
+ .getMonths(date.year)
933
+ .find((m) => m.month === value);
934
+ }
935
+ catch (_) { }
936
+ date = { ...date, monthCode: month ? month.monthCode : "" };
937
+ }
938
+ if (field === "year" && value !== null) {
939
+ try {
940
+ const months = this.adapter.getMonths(value);
941
+ const month = months.find((m) => m.monthCode === date.monthCode);
942
+ if (month)
943
+ date = { ...date, month: month.month };
944
+ }
945
+ catch (_) { }
946
+ }
947
+ draft.date = date;
948
+ }
949
+ else if (field === "hour" && this.effectiveHourCycle === "h12")
950
+ draft.hour =
951
+ value === null
952
+ ? null
953
+ : value >= 1 && value <= 12
954
+ ? (value % 12) + ((draft.hour || 0) >= 12 ? 12 : 0)
955
+ : 24 + value;
956
+ else
957
+ draft[field] = value;
958
+ this.check();
959
+ }
960
+ displayHour(draft) {
961
+ return draft.hour === null
962
+ ? null
963
+ : this.effectiveHourCycle === "h12"
964
+ ? draft.hour % 12 || 12
965
+ : draft.hour;
966
+ }
967
+ period(index, period) {
968
+ if (this[WklyPickerInputsPropertyKeys.Disabled])
969
+ return;
970
+ if (period === "24")
971
+ this.effectiveHourCycle = "h24";
972
+ else {
973
+ this.effectiveHourCycle = "h12";
974
+ this.drafts[index].hour =
975
+ ((this.drafts[index].hour || 0) % 12) + (period === "pm" ? 12 : 0);
976
+ this.drafts[index].present = true;
977
+ this.finish();
978
+ }
979
+ }
980
+ selected(day) {
981
+ return this.drafts.some((d) => {
982
+ try {
983
+ return d.present && this.adapter.dateToEpochDay(d.date) === day;
984
+ }
985
+ catch (_) {
986
+ return false;
987
+ }
988
+ });
989
+ }
990
+ inRange(day) {
991
+ if (!this.isRange || !this.drafts.every((d) => d.present))
992
+ return false;
993
+ try {
994
+ const a = this.adapter.dateToEpochDay(this.drafts[0].date), b = this.adapter.dateToEpochDay(this.drafts[1].date);
995
+ return day > Math.min(a, b) && day < Math.max(a, b);
996
+ }
997
+ catch (_) {
998
+ return false;
999
+ }
1000
+ }
1001
+ dayDisabled(day) {
1002
+ if (day < this.firstSupportedDay || day > this.lastSupportedDay)
1003
+ return true;
1004
+ try {
1005
+ const date = this.adapter.epochDayToDate(day);
1006
+ const isDateDisabled = this[WklyPickerInputsPropertyKeys.IsDateDisabled];
1007
+ if (isDateDisabled &&
1008
+ isDateDisabled(day, {
1009
+ mode: this[WklyPickerInputsPropertyKeys.Mode],
1010
+ endpoint: this.isRange
1011
+ ? this.drafts[0]?.present && !this.drafts[1]?.present
1012
+ ? "end"
1013
+ : "start"
1014
+ : "single",
1015
+ calendarDate: date,
1016
+ }))
1017
+ return true;
1018
+ const min = this[WklyPickerInputsPropertyKeys.Min];
1019
+ const max = this[WklyPickerInputsPropertyKeys.Max];
1020
+ if (min && day < decodeIso(min).epochDay)
1021
+ return true;
1022
+ if (max && day > decodeIso(max).epochDay)
1023
+ return true;
1024
+ return false;
1025
+ }
1026
+ catch (_) {
1027
+ return true;
1028
+ }
1029
+ }
1030
+ select(day) {
1031
+ if (this[WklyPickerInputsPropertyKeys.Disabled] || this.dayDisabled(day))
1032
+ return;
1033
+ this.focused = day;
1034
+ const index = this.isRange && this.drafts[0].present && !this.drafts[1].present ? 1 : 0;
1035
+ if (this.isRange && index === 0)
1036
+ this.drafts[1].present = false;
1037
+ delete this.drafts[index].unsupportedEpochDay;
1038
+ this.drafts[index].date = this.adapter.epochDayToDate(day);
1039
+ this.drafts[index].present = true;
1040
+ this.orderDrafts();
1041
+ this.renderRows();
1042
+ this.finish();
1043
+ if (this.presentation === "transient" &&
1044
+ this[WklyPickerInputsPropertyKeys.Mode] === "date" &&
1045
+ this.viewMode === "calendar")
1046
+ this.submit("auto-submit");
1047
+ }
1048
+ key(event, day) {
1049
+ let delta = 0;
1050
+ if (event.key === "ArrowLeft")
1051
+ delta = -1;
1052
+ if (event.key === "ArrowRight")
1053
+ delta = 1;
1054
+ if (event.key === "ArrowUp")
1055
+ delta = -7;
1056
+ if (event.key === "ArrowDown")
1057
+ delta = 7;
1058
+ if (event.key === "PageUp")
1059
+ delta = -7 * (event.shiftKey ? this.visibleCount : 1);
1060
+ if (event.key === "PageDown")
1061
+ delta = 7 * (event.shiftKey ? this.visibleCount : 1);
1062
+ if (event.key === "Home") {
1063
+ event.preventDefault();
1064
+ this.scrollToEpochDay(this.today, { focus: true });
1065
+ }
1066
+ if (delta) {
1067
+ event.preventDefault();
1068
+ const target = day + delta;
1069
+ if (target >= this.firstSupportedDay && target <= this.lastSupportedDay)
1070
+ this.scrollToEpochDay(target, { focus: true });
1071
+ }
1072
+ }
1073
+ position(day, preset = false, options = {}) {
1074
+ day = Math.max(this.firstSupportedDay, Math.min(this.lastSupportedDay, day));
1075
+ this.anchorWeek = absoluteWeekOf(day, this.effectiveOffset);
1076
+ const viewportPreset = this[WklyPickerInputsPropertyKeys.ViewportPreset];
1077
+ this.clipMonth = preset && viewportPreset.kind === "full-month";
1078
+ if (preset && viewportPreset.kind !== "weeks") {
1079
+ const d = this.adapter.epochDayToDate(day);
1080
+ this.initialMonth = d.year + "/" + d.monthCode;
1081
+ const [start, end] = calendarMonthBounds(this.adapter, day);
1082
+ this.firstWeek = absoluteWeekOf(start, this.effectiveOffset);
1083
+ this.visibleCount =
1084
+ absoluteWeekOf(end, this.effectiveOffset) - this.firstWeek + 1;
1085
+ if (viewportPreset.kind === "full-month-and-around" &&
1086
+ !this.configErrors.length) {
1087
+ const before = viewportPreset.extraWeeksBefore || 0, after = viewportPreset.extraWeeksAfter || 0;
1088
+ this.firstWeek -= before;
1089
+ this.visibleCount += before + after;
1090
+ }
1091
+ }
1092
+ else {
1093
+ if (viewportPreset.kind === "weeks")
1094
+ this.visibleCount = this.configErrors.length
1095
+ ? 6
1096
+ : viewportPreset.visibleWeekCount;
1097
+ this.firstWeek =
1098
+ this.anchorWeek -
1099
+ (options.align === "start"
1100
+ ? 0
1101
+ : options.align === "end"
1102
+ ? this.visibleCount - 1
1103
+ : Math.floor(this.visibleCount / 2));
1104
+ }
1105
+ this.firstWeek = this.clampFirstWeek(this.firstWeek);
1106
+ this.baseWeek = this.firstWeek - 1000;
1107
+ this.renderRows();
1108
+ // Apply the new runway before writing scrollTop or locating a focus target.
1109
+ this.changeDetector.detectChanges();
1110
+ this.resetScroll();
1111
+ }
1112
+ resetScroll() {
1113
+ // Round week boundaries to avoid scrollTop truncation under CSS zoom.
1114
+ if (this.scroller)
1115
+ this.scroller.nativeElement.scrollTop = Math.round(1000 * this.rowHeight);
1116
+ }
1117
+ scroll(event) {
1118
+ const element = event.target;
1119
+ this.snapPending = true;
1120
+ this.scheduleSnap();
1121
+ // Quantize displacement around the reset point, equally in both directions.
1122
+ const relativeRows = element.scrollTop / this.rowHeight - 1000;
1123
+ const index = 1000 + Math.sign(relativeRows) * Math.round(Math.abs(relativeRows));
1124
+ const requestedFirst = this.baseWeek + index;
1125
+ const first = this.clampFirstWeek(requestedFirst);
1126
+ if (requestedFirst !== first) {
1127
+ element.scrollTop = Math.round((first - this.baseWeek) * this.rowHeight);
1128
+ }
1129
+ if (first === this.firstWeek)
1130
+ return;
1131
+ this.clipMonth = false;
1132
+ this.firstWeek = first;
1133
+ this.anchorWeek = first + Math.floor(this.visibleCount / 2);
1134
+ if (index < 100 || index > 1900) {
1135
+ // Preserve signed displacement from this week; modulo turns fractional
1136
+ // rounding just below a boundary into almost a full row after rebasing.
1137
+ const offset = element.scrollTop - (first - this.baseWeek) * this.rowHeight;
1138
+ this.baseWeek = first - 1000;
1139
+ element.scrollTop = Math.round(1000 * this.rowHeight + offset);
1140
+ }
1141
+ this.renderRows();
1142
+ }
1143
+ scheduleSnap() {
1144
+ if (this.scrollEndTimer)
1145
+ clearTimeout(this.scrollEndTimer);
1146
+ this.scrollEndTimer = setTimeout(() => this.snapWeek(), 200);
1147
+ }
1148
+ snapWeek() {
1149
+ if (this.scrollEndTimer)
1150
+ clearTimeout(this.scrollEndTimer);
1151
+ this.scrollEndTimer = undefined;
1152
+ if (!this.snapPending || !this.scroller)
1153
+ return;
1154
+ this.snapPending = false;
1155
+ // Align the current virtual week without rebuilding or rebasing its rows.
1156
+ const element = this.scroller.nativeElement;
1157
+ const target = Math.round((this.firstWeek - this.baseWeek) * this.rowHeight);
1158
+ if (element.scrollTop !== target)
1159
+ element.scrollTop = target;
1160
+ }
1161
+ showFirstWeek(week) {
1162
+ const first = this.clampFirstWeek(week);
1163
+ if (first === this.firstWeek)
1164
+ return;
1165
+ this.clipMonth = false;
1166
+ this.firstWeek = first;
1167
+ this.anchorWeek = first + Math.floor(this.visibleCount / 2);
1168
+ this.baseWeek = first - 1000;
1169
+ this.renderRows();
1170
+ this.resetScroll();
1171
+ }
1172
+ canMoveWeek(delta) {
1173
+ return this.clampFirstWeek(this.firstWeek + delta) !== this.firstWeek;
1174
+ }
1175
+ moveWeek(delta) {
1176
+ if (!this[WklyPickerInputsPropertyKeys.Disabled])
1177
+ this.showFirstWeek(this.firstWeek + delta);
1178
+ }
1179
+ renderRows() {
1180
+ // Keep the virtual scroll offset here; row data is shared across Angular versions.
1181
+ const overscan = Math.max(0, Math.min(50, this[WklyPickerInputsPropertyKeys.OverscanWeeks] || 0));
1182
+ const start = this.firstWeek - overscan;
1183
+ this.paddingTop = (start - this.baseWeek) * this.rowHeight;
1184
+ this.rows = createWeekRows({
1185
+ generator: this.generator,
1186
+ adapter: this.adapter,
1187
+ startWeek: start,
1188
+ count: this.visibleCount + 2 * overscan,
1189
+ firstVisibleWeek: this.firstWeek,
1190
+ firstSupportedDay: this.firstSupportedDay,
1191
+ lastSupportedDay: this.lastSupportedDay,
1192
+ clipMonth: this.clipMonth,
1193
+ initialMonth: this.initialMonth,
1194
+ weekLabelMode: this[WklyPickerInputsPropertyKeys.WeekLabelMode],
1195
+ weekLabelFormatter: this[WklyPickerInputsPropertyKeys.WeekLabelFormatter] || null,
1196
+ isDayDisabled: (day) => this.dayDisabled(day),
1197
+ });
1198
+ this[WklyPickerOutputsPropertyKeys.ViewportChange].emit({
1199
+ firstVisibleAbsoluteWeek: this.firstWeek,
1200
+ lastVisibleAbsoluteWeek: this.firstWeek + this.visibleCount - 1,
1201
+ anchorAbsoluteWeek: this.anchorWeek,
1202
+ });
1203
+ }
1204
+ // Retain day DOM nodes and keyboard focus when row metadata is regenerated.
1205
+ trackCell(_i, cell) {
1206
+ return cell.epochDay;
1207
+ }
1208
+ trackRow(_i, row) {
1209
+ return row.week.absoluteWeek;
1210
+ }
1211
+ scrollToEpochDay(day, options = {}) {
1212
+ integer(day);
1213
+ this.adapter.epochDayToDate(day);
1214
+ day = Math.max(this.firstSupportedDay, Math.min(this.lastSupportedDay, day));
1215
+ // position renders synchronously; publish the tab stop before that render.
1216
+ if (options.focus)
1217
+ this.focused = day;
1218
+ this.position(day, false, options);
1219
+ if (options.select)
1220
+ this.select(day);
1221
+ if (options.focus)
1222
+ this.focusDay();
1223
+ }
1224
+ scrollToAbsoluteWeek(week, options = {}) {
1225
+ // A boundary week can start before the adapter's first supported day.
1226
+ const first = firstEpochDayOf(week, this.effectiveOffset);
1227
+ this.scrollToEpochDay(week === this.firstSupportedWeek
1228
+ ? Math.max(first, this.firstSupportedDay)
1229
+ : first, options);
1230
+ }
1231
+ scrollToCalendarDate(date, options = {}) {
1232
+ this.scrollToEpochDay(this.adapter.dateToEpochDay(date), options);
1233
+ }
1234
+ scrollToValue(value, options = {}) {
1235
+ this.scrollToEpochDay(decodeIso(value).epochDay, options);
1236
+ }
1237
+ focusDay() {
1238
+ if (!this.browser)
1239
+ return;
1240
+ setTimeout(() => {
1241
+ if (this.destroyed)
1242
+ return;
1243
+ this.changeDetector.detectChanges();
1244
+ const day = this.host.nativeElement.querySelector('[data-day="' + this.focused + '"]');
1245
+ const fallback = this.host.nativeElement.querySelector("button:not(:disabled),input:not(:disabled)");
1246
+ (day || fallback)?.focus({ preventScroll: true });
1247
+ });
1248
+ }
1249
+ }
1250
+ WklyDateTimePickerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerComponent, deps: [{ token: LOCALE_ID }, { token: WKLY_CONFIG }, { token: WKLY_CLOCK }, { token: WKLY_LOCALIZATION }, { token: WKLY_TRANSLATIONS }, { token: PLATFORM_ID }, { token: i0.ElementRef }, { token: i0.ChangeDetectorRef }], target: i0.ɵɵFactoryTarget.Component });
1251
+ WklyDateTimePickerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "13.4.0", type: WklyDateTimePickerComponent, selector: "wkly-datetime-picker", providers: [
1252
+ {
1253
+ provide: NG_VALUE_ACCESSOR,
1254
+ useExisting: forwardRef(() => WklyDateTimePickerComponent),
1255
+ multi: true,
1256
+ },
1257
+ {
1258
+ provide: NG_VALIDATORS,
1259
+ useExisting: forwardRef(() => WklyDateTimePickerComponent),
1260
+ multi: true,
1261
+ },
1262
+ ], viewQueries: [{ propertyName: "scroller", first: true, predicate: ["scroller"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<section\n class=\"wkly\"\n [attr.dir]=\"direction\"\n [attr.aria-label]=\"\n this[WklyPickerInputsPropertyKeys.AriaLabel] || 'Date and time picker'\n \"\n [attr.aria-describedby]=\"this[WklyPickerInputsPropertyKeys.AriaDescribedBy]\"\n (focusout)=\"touched()\"\n>\n <header class=\"toolbar\">\n <button\n *ngIf=\"hasDate\"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"t(viewMode === 'calendar' ? 'manual' : 'calendar')\"\n (click)=\"toggleView()\"\n >\n {{ viewMode === \"calendar\" ? \"\u2637\" : \"\u25A6\" }}\n </button>\n <span *ngIf=\"hasDate\" class=\"year-control\">{{ title }}</span>\n <span class=\"spacer\"></span\n ><button\n type=\"button\"\n class=\"now\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n (click)=\"now()\"\n >\n {{ t(\"now\") }}\n </button>\n <button\n *ngIf=\"presentation === 'transient'\"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"t('close')\"\n (click)=\"cancel()\"\n >\n \u00D7\n </button>\n </header>\n <ng-container *ngIf=\"hasDate && viewMode === 'calendar'\">\n <div\n role=\"grid\"\n [attr.aria-label]=\"\n this[WklyPickerInputsPropertyKeys.AriaLabel] || 'Calendar'\n \"\n [attr.aria-multiselectable]=\"isRange\"\n >\n <div\n role=\"row\"\n class=\"week-head\"\n [class.no-label]=\"\n compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] === 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n >\n <span\n *ngIf=\"\n !compact &&\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] !== 'hidden' ||\n this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n role=\"columnheader\"\n aria-label=\"Week\"\n ></span\n ><span *ngFor=\"let day of weekdays\" role=\"columnheader\">{{ day }}</span>\n </div>\n <div\n #scroller\n class=\"week-scroll\"\n [style.height.px]=\"visibleCount * rowHeight\"\n (scroll)=\"scroll($event)\"\n (scrollend)=\"snapWeek()\"\n >\n <div [style.height.px]=\"scrollHeight\" class=\"scroll-space\">\n <div class=\"rows\" [style.top.px]=\"paddingTop\">\n <div\n *ngFor=\"let row of rows; trackBy: trackRow\"\n role=\"row\"\n class=\"week-row\"\n [class.no-label]=\"\n compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] ===\n 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n >\n <span\n *ngIf=\"\n !compact &&\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] !==\n 'hidden' ||\n this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n role=\"rowheader\"\n class=\"week-number\"\n >{{ row.label }}</span\n >\n <div\n *ngFor=\"\n let cell of row.cells;\n let dayIndex = index;\n trackBy: trackCell\n \"\n role=\"gridcell\"\n [attr.data-weekday-index]=\"dayIndex\"\n [attr.aria-colindex]=\"\n dayIndex +\n (compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] ===\n 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n ? 1\n : 2)\n \"\n [attr.aria-selected]=\"selected(cell.epochDay)\"\n [attr.aria-disabled]=\"\n cell.disabled || this[WklyPickerInputsPropertyKeys.Disabled]\n \"\n [class.range]=\"inRange(cell.epochDay)\"\n [class.hidden]=\"cell.hidden\"\n [class.odd-month]=\"cell.date && cell.date.month % 2 === 1\"\n >\n <span [class]=\"'annotation annotation--' + dayIndex\">{{\n cell.annotation\n }}</span>\n <button\n type=\"button\"\n class=\"day\"\n [attr.data-day]=\"cell.epochDay\"\n [attr.aria-label]=\"cell.accessible\"\n [attr.aria-current]=\"cell.epochDay === today ? 'date' : null\"\n [attr.aria-disabled]=\"\n cell.disabled || this[WklyPickerInputsPropertyKeys.Disabled]\n \"\n [attr.tabindex]=\"\n !cell.hidden && cell.epochDay === focused ? 0 : -1\n \"\n [class.selected]=\"selected(cell.epochDay)\"\n [class.today]=\"cell.epochDay === today\"\n (focus)=\"focused = cell.epochDay\"\n (click)=\"select(cell.epochDay)\"\n (keydown)=\"key($event, cell.epochDay)\"\n >\n {{ cell.label }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"week-navigation\">\n <button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] || !canMoveWeek(-1)\n \"\n [attr.aria-label]=\"t('previous')\"\n (click)=\"moveWeek(-1)\"\n >\n \u2191</button\n ><span>{{ title }}</span\n ><button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] || !canMoveWeek(1)\n \"\n [attr.aria-label]=\"t('next')\"\n (click)=\"moveWeek(1)\"\n >\n \u2193\n </button>\n </div>\n </ng-container>\n <ng-container\n *ngFor=\"let draft of drafts; let i = index; trackBy: trackDraft\"\n >\n <fieldset\n *ngIf=\"(i === 0 || isRange) && (hasTime || viewMode === 'manual')\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"isRange ? t(i === 0 ? 'start' : 'end') : null\"\n >\n <legend *ngIf=\"isRange\">\n <ng-container\n *ngIf=\"\n i === 1 && hasDate && viewMode === 'manual';\n else endpointLabel\n \"\n >\n <span class=\"end-view-toggle\">\n <button\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"endView === 'date'\"\n (click)=\"toggleEndView('date')\"\n >\n {{ t(\"end\") }}\n </button>\n <button\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"endView === 'days'\"\n (click)=\"toggleEndView('days')\"\n >\n {{ inDaysLabel }}\n </button>\n </span>\n </ng-container>\n <ng-template #endpointLabel>{{\n t(i === 0 ? \"start\" : \"end\")\n }}</ng-template>\n </legend>\n <div\n *ngIf=\"\n i === 1 && hasDate && viewMode === 'manual' && endView === 'days'\n \"\n class=\"date-fields in-days-fields\"\n >\n <span class=\"resulting-end-date\" [attr.aria-label]=\"t('endDate')\">{{\n resultingEndDate\n }}</span>\n <wkly-field\n [label]=\"t('days')\"\n [hideLabel]=\"true\"\n [previousLabel]=\"t('daysPrevious')\"\n [nextLabel]=\"t('daysNext')\"\n [locale]=\"effectiveLocale\"\n [value]=\"inDays\"\n [min]=\"-9999\"\n [max]=\"9999\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"days($event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n </div>\n <div\n *ngIf=\"\n hasDate && viewMode === 'manual' && (i === 0 || endView === 'date')\n \"\n class=\"date-fields\"\n >\n <wkly-field\n [label]=\"t('day')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.day\"\n [min]=\"1\"\n [max]=\"31\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'day', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('month')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.month\"\n [min]=\"1\"\n [max]=\"monthCount(draft)\"\n [labels]=\"months(draft)\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'month', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('year')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.year\"\n [min]=\"adapter.supportedYearRange[0]\"\n [max]=\"adapter.supportedYearRange[1]\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'year', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n </div>\n <div\n *ngIf=\"hasTime\"\n class=\"time-fields\"\n [class.seconds]=\"this[WklyPickerInputsPropertyKeys.ShowSeconds]\"\n >\n <wkly-field\n [label]=\"t('hour')\"\n [locale]=\"effectiveLocale\"\n [value]=\"displayHour(draft)\"\n [min]=\"effectiveHourCycle === 'h12' ? 1 : 0\"\n [max]=\"effectiveHourCycle === 'h12' ? 12 : 23\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'hour', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('minute')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.minute\"\n [max]=\"59\"\n [step]=\"\n this[WklyPickerInputsPropertyKeys.MinuteStep] > 0 &&\n 60 % this[WklyPickerInputsPropertyKeys.MinuteStep] === 0\n ? this[WklyPickerInputsPropertyKeys.MinuteStep]\n : 1\n \"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'minute', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n *ngIf=\"this[WklyPickerInputsPropertyKeys.ShowSeconds]\"\n [label]=\"t('second')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.second\"\n [max]=\"59\"\n [step]=\"\n this[WklyPickerInputsPropertyKeys.SecondStep] > 0 &&\n 60 % this[WklyPickerInputsPropertyKeys.SecondStep] === 0\n ? this[WklyPickerInputsPropertyKeys.SecondStep]\n : 1\n \"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'second', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <div class=\"period\">\n <button\n *ngIf=\"\n effectiveHourCycle === 'h12' ||\n this[WklyPickerInputsPropertyKeys.HourCycle] === 'switchable'\n \"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"\n effectiveHourCycle === 'h12' && (draft.hour || 0) < 12\n \"\n (click)=\"period(i, 'am')\"\n >\n {{ t(\"am\") }}</button\n ><button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] ||\n this[WklyPickerInputsPropertyKeys.HourCycle] !== 'switchable'\n \"\n [attr.aria-pressed]=\"effectiveHourCycle === 'h24'\"\n (click)=\"period(i, '24')\"\n >\n 24</button\n ><button\n *ngIf=\"\n effectiveHourCycle === 'h12' ||\n this[WklyPickerInputsPropertyKeys.HourCycle] === 'switchable'\n \"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"\n effectiveHourCycle === 'h12' && (draft.hour || 0) >= 12\n \"\n (click)=\"period(i, 'pm')\"\n >\n {{ t(\"pm\") }}\n </button>\n </div>\n </div>\n </fieldset>\n </ng-container>\n <div class=\"validation\" role=\"status\" aria-live=\"polite\">\n <p *ngFor=\"let err of errors\">! {{ t(err.messageKey) }}</p>\n </div>\n <footer *ngIf=\"submitVisible\">\n <button\n type=\"button\"\n class=\"confirm\"\n [disabled]=\"!canSubmit\"\n (click)=\"submit()\"\n >\n {{ t(\"confirm\") }}\n </button>\n </footer>\n</section>\n", styles: [":host{display:block;width:100%;box-sizing:border-box;--wkly-background-color: #fff;--wkly-background-color-alternate: #fafafa;--wkly-text-color: #192c28;--wkly-muted-color: #52635e;--wkly-border-color: #dce5e1;--wkly-accent-color: #176c55;--wkly-accent-color-alternate: #6ea494;--wkly-accent-text-color: #fff;--wkly-range-color: #e5f1ee;--wkly-error-color: #b42318;--wkly-focus-color: #245bd6;--wkly-size-multiplier: 1;--wkly-size-unit: 3.5em;color:var(--wkly-text-color);font:14px/1.4 system-ui,sans-serif;container-type:inline-size}.wkly{background:var(--wkly-background-color);border:1px solid var(--wkly-border-color);border-radius:14px;overflow:hidden;min-width:0;font-size:calc(14px*clamp(1,var(--wkly-size-multiplier),1.5))}button{font:inherit;color:inherit;min-width:var(--wkly-size-unit);min-height:var(--wkly-size-unit);border:0;background:transparent;border-radius:8px;cursor:pointer}button:hover:not(:disabled):not([aria-disabled=\"true\"]){background:var(--wkly-accent-color-alternate)}button:disabled,button[aria-disabled=true]{opacity:.4;cursor:default}button:focus-visible{outline:2px solid var(--wkly-focus-color);outline-offset:-2px}.toolbar{display:flex;align-items:center;padding:8px;gap:3px;border-bottom:1px solid var(--wkly-border-color)}.spacer{flex:1}.year-control{padding:0 6px;font-weight:650;text-align:start;line-height:1.2}.now{color:var(--wkly-accent-color);font-weight:650}.week-head,.week-row{display:grid;grid-template-columns:28px repeat(7,minmax(0,1fr))}.week-head{font-size:.85em;color:var(--wkly-muted-color);height:34px;align-items:center;text-align:center}.week-row{height:calc(var(--wkly-size-unit) * clamp(1,var(--wkly-size-multiplier),1));align-items:end}.no-label{grid-template-columns:repeat(7,minmax(0,1fr))}.week-scroll{overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;overflow-anchor:none;scrollbar-width:thin;max-height:65vh;touch-action:pan-y}.scroll-space{position:relative}.rows{position:absolute;left:0;right:0}.week-number{font-size:.85em;text-align:center;align-self:end;line-height:var(--wkly-size-unit);color:var(--wkly-muted-color)}[role=gridcell]{position:relative;min-width:0;height:var(--wkly-size-unit);text-align:center}[role=gridcell].odd-month:not(.range):not(.today){background:var(--wkly-background-color-alternate)}.day{width:100%;min-width:0;height:var(--wkly-size-unit);padding:0;border-radius:8px}.annotation{position:absolute;bottom:.25em;white-space:nowrap;font-size:1.25em;font-weight:650;line-height:1;pointer-events:none;z-index:1;color:var(--wkly-muted-color);color:color-mix(in srgb,var(--wkly-muted-color) 50%,transparent);text-shadow:0 0 2px --wkly-background-color,0 0 4px --wkly-background-color}.odd-month .annotation{text-shadow:0 0 2px --wkly-background-color-alternate,0 0 4px --wkly-background-color-alternate}.annotation:empty{display:none}.annotation--0{inset-inline-start:10%;bottom:1.75em}.annotation--1{inset-inline-start:-5%}.annotation--2{inset-inline-start:-20%}.annotation--3{inset-inline-start:-50%;inset-inline-end:-50%}.annotation--4{inset-inline-end:-20%}.annotation--5{inset-inline-end:-5%}.annotation--6{inset-inline-end:10%}.range{background:var(--wkly-range-color)}.day.selected{background:var(--wkly-accent-color);color:var(--wkly-accent-text-color);font-weight:700}.today:after{content:\"\";display:block;width:5px;height:5px;background:currentColor;border-radius:50%;position:absolute;bottom:2px;left:calc(50% - 2px)}.today{font-weight:750;box-shadow:inset 0 0 0 1px var(--wkly-accent-color)}.hidden{visibility:hidden}.week-navigation{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--wkly-border-color);font-size:.85em;color:var(--wkly-muted-color)}fieldset{border:0;padding:0 12px;margin:0;min-width:0}legend{padding-top:.85em;font-weight:650;color:var(--wkly-accent-color)}.date-fields{display:grid;grid-template-columns:1fr 2fr 1.4fr;grid-gap:7px;gap:7px;padding:12px 0}.end-view-toggle{display:inline-flex}.end-view-toggle button{min-height:0;min-width:0;padding:0 6px;border-radius:0;line-height:inherit}.end-view-toggle button:first-child{padding-inline-start:0}.end-view-toggle button+button{border-inline-start:1px solid var(--wkly-text-color)}.end-view-toggle button[aria-pressed=false]{color:var(--wkly-muted-color);font-weight:400}.in-days-fields{grid-template-columns:minmax(0,1fr);gap:0;text-align:center}.resulting-end-date{font-size:11px;color:var(--wkly-muted-color);height:1.4em;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.time-fields{display:grid;grid-template-columns:1fr 1fr 52px;grid-gap:8px;gap:8px;padding:14px 0;border-top:1px solid var(--wkly-border-color)}.time-fields.seconds{grid-template-columns:1fr 1fr 1fr 48px}.period{display:flex;flex-direction:column;justify-content:center;gap:2px;padding-top:1.25em}.period button{font-size:.85em}.period [aria-pressed=true]{background:var(--wkly-range-color);box-shadow:inset 0 0 0 1px var(--wkly-accent-color);font-weight:700}.validation{color:var(--wkly-error-color);font-size:.85em}.validation p{margin:.5em .85em}footer{padding:12px;border-top:1px solid var(--wkly-border-color)}.confirm{background:var(--wkly-accent-color);color:var(--wkly-accent-text-color);width:100%;font-weight:650}.confirm:hover:not(:disabled){background:var(--wkly-accent-color-alternate)}@media (forced-colors: active){.day.selected{outline:2px solid Highlight}.range{border-bottom:2px solid Highlight}.today{outline:1px dashed CanvasText}}@media (prefers-reduced-motion: reduce){*{scroll-behavior:auto!important;animation:none!important}}\n"], components: [{ type: WklyFieldComponent, selector: "wkly-field", inputs: ["value", "label", "hideLabel", "previousLabel", "nextLabel", "min", "max", "step", "locale", "disabled", "invalid", "labels"], outputs: ["valueChange", "complete"] }], directives: [{ type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
1263
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerComponent, decorators: [{
1264
+ type: Component,
1265
+ args: [{ selector: "wkly-datetime-picker", providers: [
1266
+ {
1267
+ provide: NG_VALUE_ACCESSOR,
1268
+ useExisting: forwardRef(() => WklyDateTimePickerComponent),
1269
+ multi: true,
1270
+ },
1271
+ {
1272
+ provide: NG_VALIDATORS,
1273
+ useExisting: forwardRef(() => WklyDateTimePickerComponent),
1274
+ multi: true,
1275
+ },
1276
+ ], template: "<section\n class=\"wkly\"\n [attr.dir]=\"direction\"\n [attr.aria-label]=\"\n this[WklyPickerInputsPropertyKeys.AriaLabel] || 'Date and time picker'\n \"\n [attr.aria-describedby]=\"this[WklyPickerInputsPropertyKeys.AriaDescribedBy]\"\n (focusout)=\"touched()\"\n>\n <header class=\"toolbar\">\n <button\n *ngIf=\"hasDate\"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"t(viewMode === 'calendar' ? 'manual' : 'calendar')\"\n (click)=\"toggleView()\"\n >\n {{ viewMode === \"calendar\" ? \"\u2637\" : \"\u25A6\" }}\n </button>\n <span *ngIf=\"hasDate\" class=\"year-control\">{{ title }}</span>\n <span class=\"spacer\"></span\n ><button\n type=\"button\"\n class=\"now\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n (click)=\"now()\"\n >\n {{ t(\"now\") }}\n </button>\n <button\n *ngIf=\"presentation === 'transient'\"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"t('close')\"\n (click)=\"cancel()\"\n >\n \u00D7\n </button>\n </header>\n <ng-container *ngIf=\"hasDate && viewMode === 'calendar'\">\n <div\n role=\"grid\"\n [attr.aria-label]=\"\n this[WklyPickerInputsPropertyKeys.AriaLabel] || 'Calendar'\n \"\n [attr.aria-multiselectable]=\"isRange\"\n >\n <div\n role=\"row\"\n class=\"week-head\"\n [class.no-label]=\"\n compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] === 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n >\n <span\n *ngIf=\"\n !compact &&\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] !== 'hidden' ||\n this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n role=\"columnheader\"\n aria-label=\"Week\"\n ></span\n ><span *ngFor=\"let day of weekdays\" role=\"columnheader\">{{ day }}</span>\n </div>\n <div\n #scroller\n class=\"week-scroll\"\n [style.height.px]=\"visibleCount * rowHeight\"\n (scroll)=\"scroll($event)\"\n (scrollend)=\"snapWeek()\"\n >\n <div [style.height.px]=\"scrollHeight\" class=\"scroll-space\">\n <div class=\"rows\" [style.top.px]=\"paddingTop\">\n <div\n *ngFor=\"let row of rows; trackBy: trackRow\"\n role=\"row\"\n class=\"week-row\"\n [class.no-label]=\"\n compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] ===\n 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n >\n <span\n *ngIf=\"\n !compact &&\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] !==\n 'hidden' ||\n this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n \"\n role=\"rowheader\"\n class=\"week-number\"\n >{{ row.label }}</span\n >\n <div\n *ngFor=\"\n let cell of row.cells;\n let dayIndex = index;\n trackBy: trackCell\n \"\n role=\"gridcell\"\n [attr.data-weekday-index]=\"dayIndex\"\n [attr.aria-colindex]=\"\n dayIndex +\n (compact ||\n (this[WklyPickerInputsPropertyKeys.WeekLabelMode] ===\n 'hidden' &&\n !this[WklyPickerInputsPropertyKeys.WeekLabelFormatter])\n ? 1\n : 2)\n \"\n [attr.aria-selected]=\"selected(cell.epochDay)\"\n [attr.aria-disabled]=\"\n cell.disabled || this[WklyPickerInputsPropertyKeys.Disabled]\n \"\n [class.range]=\"inRange(cell.epochDay)\"\n [class.hidden]=\"cell.hidden\"\n [class.odd-month]=\"cell.date && cell.date.month % 2 === 1\"\n >\n <span [class]=\"'annotation annotation--' + dayIndex\">{{\n cell.annotation\n }}</span>\n <button\n type=\"button\"\n class=\"day\"\n [attr.data-day]=\"cell.epochDay\"\n [attr.aria-label]=\"cell.accessible\"\n [attr.aria-current]=\"cell.epochDay === today ? 'date' : null\"\n [attr.aria-disabled]=\"\n cell.disabled || this[WklyPickerInputsPropertyKeys.Disabled]\n \"\n [attr.tabindex]=\"\n !cell.hidden && cell.epochDay === focused ? 0 : -1\n \"\n [class.selected]=\"selected(cell.epochDay)\"\n [class.today]=\"cell.epochDay === today\"\n (focus)=\"focused = cell.epochDay\"\n (click)=\"select(cell.epochDay)\"\n (keydown)=\"key($event, cell.epochDay)\"\n >\n {{ cell.label }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </div>\n </div>\n <div class=\"week-navigation\">\n <button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] || !canMoveWeek(-1)\n \"\n [attr.aria-label]=\"t('previous')\"\n (click)=\"moveWeek(-1)\"\n >\n \u2191</button\n ><span>{{ title }}</span\n ><button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] || !canMoveWeek(1)\n \"\n [attr.aria-label]=\"t('next')\"\n (click)=\"moveWeek(1)\"\n >\n \u2193\n </button>\n </div>\n </ng-container>\n <ng-container\n *ngFor=\"let draft of drafts; let i = index; trackBy: trackDraft\"\n >\n <fieldset\n *ngIf=\"(i === 0 || isRange) && (hasTime || viewMode === 'manual')\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-label]=\"isRange ? t(i === 0 ? 'start' : 'end') : null\"\n >\n <legend *ngIf=\"isRange\">\n <ng-container\n *ngIf=\"\n i === 1 && hasDate && viewMode === 'manual';\n else endpointLabel\n \"\n >\n <span class=\"end-view-toggle\">\n <button\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"endView === 'date'\"\n (click)=\"toggleEndView('date')\"\n >\n {{ t(\"end\") }}\n </button>\n <button\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"endView === 'days'\"\n (click)=\"toggleEndView('days')\"\n >\n {{ inDaysLabel }}\n </button>\n </span>\n </ng-container>\n <ng-template #endpointLabel>{{\n t(i === 0 ? \"start\" : \"end\")\n }}</ng-template>\n </legend>\n <div\n *ngIf=\"\n i === 1 && hasDate && viewMode === 'manual' && endView === 'days'\n \"\n class=\"date-fields in-days-fields\"\n >\n <span class=\"resulting-end-date\" [attr.aria-label]=\"t('endDate')\">{{\n resultingEndDate\n }}</span>\n <wkly-field\n [label]=\"t('days')\"\n [hideLabel]=\"true\"\n [previousLabel]=\"t('daysPrevious')\"\n [nextLabel]=\"t('daysNext')\"\n [locale]=\"effectiveLocale\"\n [value]=\"inDays\"\n [min]=\"-9999\"\n [max]=\"9999\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"days($event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n </div>\n <div\n *ngIf=\"\n hasDate && viewMode === 'manual' && (i === 0 || endView === 'date')\n \"\n class=\"date-fields\"\n >\n <wkly-field\n [label]=\"t('day')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.day\"\n [min]=\"1\"\n [max]=\"31\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'day', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('month')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.month\"\n [min]=\"1\"\n [max]=\"monthCount(draft)\"\n [labels]=\"months(draft)\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'month', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('year')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.date.year\"\n [min]=\"adapter.supportedYearRange[0]\"\n [max]=\"adapter.supportedYearRange[1]\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'year', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n </div>\n <div\n *ngIf=\"hasTime\"\n class=\"time-fields\"\n [class.seconds]=\"this[WklyPickerInputsPropertyKeys.ShowSeconds]\"\n >\n <wkly-field\n [label]=\"t('hour')\"\n [locale]=\"effectiveLocale\"\n [value]=\"displayHour(draft)\"\n [min]=\"effectiveHourCycle === 'h12' ? 1 : 0\"\n [max]=\"effectiveHourCycle === 'h12' ? 12 : 23\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'hour', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n [label]=\"t('minute')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.minute\"\n [max]=\"59\"\n [step]=\"\n this[WklyPickerInputsPropertyKeys.MinuteStep] > 0 &&\n 60 % this[WklyPickerInputsPropertyKeys.MinuteStep] === 0\n ? this[WklyPickerInputsPropertyKeys.MinuteStep]\n : 1\n \"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'minute', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <wkly-field\n *ngIf=\"this[WklyPickerInputsPropertyKeys.ShowSeconds]\"\n [label]=\"t('second')\"\n [locale]=\"effectiveLocale\"\n [value]=\"draft.second\"\n [max]=\"59\"\n [step]=\"\n this[WklyPickerInputsPropertyKeys.SecondStep] > 0 &&\n 60 % this[WklyPickerInputsPropertyKeys.SecondStep] === 0\n ? this[WklyPickerInputsPropertyKeys.SecondStep]\n : 1\n \"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [invalid]=\"!!errors.length\"\n (valueChange)=\"field(i, 'second', $event)\"\n (complete)=\"finish()\"\n ></wkly-field>\n <div class=\"period\">\n <button\n *ngIf=\"\n effectiveHourCycle === 'h12' ||\n this[WklyPickerInputsPropertyKeys.HourCycle] === 'switchable'\n \"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"\n effectiveHourCycle === 'h12' && (draft.hour || 0) < 12\n \"\n (click)=\"period(i, 'am')\"\n >\n {{ t(\"am\") }}</button\n ><button\n type=\"button\"\n [disabled]=\"\n this[WklyPickerInputsPropertyKeys.Disabled] ||\n this[WklyPickerInputsPropertyKeys.HourCycle] !== 'switchable'\n \"\n [attr.aria-pressed]=\"effectiveHourCycle === 'h24'\"\n (click)=\"period(i, '24')\"\n >\n 24</button\n ><button\n *ngIf=\"\n effectiveHourCycle === 'h12' ||\n this[WklyPickerInputsPropertyKeys.HourCycle] === 'switchable'\n \"\n type=\"button\"\n [disabled]=\"this[WklyPickerInputsPropertyKeys.Disabled]\"\n [attr.aria-pressed]=\"\n effectiveHourCycle === 'h12' && (draft.hour || 0) >= 12\n \"\n (click)=\"period(i, 'pm')\"\n >\n {{ t(\"pm\") }}\n </button>\n </div>\n </div>\n </fieldset>\n </ng-container>\n <div class=\"validation\" role=\"status\" aria-live=\"polite\">\n <p *ngFor=\"let err of errors\">! {{ t(err.messageKey) }}</p>\n </div>\n <footer *ngIf=\"submitVisible\">\n <button\n type=\"button\"\n class=\"confirm\"\n [disabled]=\"!canSubmit\"\n (click)=\"submit()\"\n >\n {{ t(\"confirm\") }}\n </button>\n </footer>\n</section>\n", styles: [":host{display:block;width:100%;box-sizing:border-box;--wkly-background-color: #fff;--wkly-background-color-alternate: #fafafa;--wkly-text-color: #192c28;--wkly-muted-color: #52635e;--wkly-border-color: #dce5e1;--wkly-accent-color: #176c55;--wkly-accent-color-alternate: #6ea494;--wkly-accent-text-color: #fff;--wkly-range-color: #e5f1ee;--wkly-error-color: #b42318;--wkly-focus-color: #245bd6;--wkly-size-multiplier: 1;--wkly-size-unit: 3.5em;color:var(--wkly-text-color);font:14px/1.4 system-ui,sans-serif;container-type:inline-size}.wkly{background:var(--wkly-background-color);border:1px solid var(--wkly-border-color);border-radius:14px;overflow:hidden;min-width:0;font-size:calc(14px*clamp(1,var(--wkly-size-multiplier),1.5))}button{font:inherit;color:inherit;min-width:var(--wkly-size-unit);min-height:var(--wkly-size-unit);border:0;background:transparent;border-radius:8px;cursor:pointer}button:hover:not(:disabled):not([aria-disabled=\"true\"]){background:var(--wkly-accent-color-alternate)}button:disabled,button[aria-disabled=true]{opacity:.4;cursor:default}button:focus-visible{outline:2px solid var(--wkly-focus-color);outline-offset:-2px}.toolbar{display:flex;align-items:center;padding:8px;gap:3px;border-bottom:1px solid var(--wkly-border-color)}.spacer{flex:1}.year-control{padding:0 6px;font-weight:650;text-align:start;line-height:1.2}.now{color:var(--wkly-accent-color);font-weight:650}.week-head,.week-row{display:grid;grid-template-columns:28px repeat(7,minmax(0,1fr))}.week-head{font-size:.85em;color:var(--wkly-muted-color);height:34px;align-items:center;text-align:center}.week-row{height:calc(var(--wkly-size-unit) * clamp(1,var(--wkly-size-multiplier),1));align-items:end}.no-label{grid-template-columns:repeat(7,minmax(0,1fr))}.week-scroll{overflow-y:auto;overflow-x:hidden;overscroll-behavior:contain;overflow-anchor:none;scrollbar-width:thin;max-height:65vh;touch-action:pan-y}.scroll-space{position:relative}.rows{position:absolute;left:0;right:0}.week-number{font-size:.85em;text-align:center;align-self:end;line-height:var(--wkly-size-unit);color:var(--wkly-muted-color)}[role=gridcell]{position:relative;min-width:0;height:var(--wkly-size-unit);text-align:center}[role=gridcell].odd-month:not(.range):not(.today){background:var(--wkly-background-color-alternate)}.day{width:100%;min-width:0;height:var(--wkly-size-unit);padding:0;border-radius:8px}.annotation{position:absolute;bottom:.25em;white-space:nowrap;font-size:1.25em;font-weight:650;line-height:1;pointer-events:none;z-index:1;color:var(--wkly-muted-color);color:color-mix(in srgb,var(--wkly-muted-color) 50%,transparent);text-shadow:0 0 2px --wkly-background-color,0 0 4px --wkly-background-color}.odd-month .annotation{text-shadow:0 0 2px --wkly-background-color-alternate,0 0 4px --wkly-background-color-alternate}.annotation:empty{display:none}.annotation--0{inset-inline-start:10%;bottom:1.75em}.annotation--1{inset-inline-start:-5%}.annotation--2{inset-inline-start:-20%}.annotation--3{inset-inline-start:-50%;inset-inline-end:-50%}.annotation--4{inset-inline-end:-20%}.annotation--5{inset-inline-end:-5%}.annotation--6{inset-inline-end:10%}.range{background:var(--wkly-range-color)}.day.selected{background:var(--wkly-accent-color);color:var(--wkly-accent-text-color);font-weight:700}.today:after{content:\"\";display:block;width:5px;height:5px;background:currentColor;border-radius:50%;position:absolute;bottom:2px;left:calc(50% - 2px)}.today{font-weight:750;box-shadow:inset 0 0 0 1px var(--wkly-accent-color)}.hidden{visibility:hidden}.week-navigation{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--wkly-border-color);font-size:.85em;color:var(--wkly-muted-color)}fieldset{border:0;padding:0 12px;margin:0;min-width:0}legend{padding-top:.85em;font-weight:650;color:var(--wkly-accent-color)}.date-fields{display:grid;grid-template-columns:1fr 2fr 1.4fr;grid-gap:7px;gap:7px;padding:12px 0}.end-view-toggle{display:inline-flex}.end-view-toggle button{min-height:0;min-width:0;padding:0 6px;border-radius:0;line-height:inherit}.end-view-toggle button:first-child{padding-inline-start:0}.end-view-toggle button+button{border-inline-start:1px solid var(--wkly-text-color)}.end-view-toggle button[aria-pressed=false]{color:var(--wkly-muted-color);font-weight:400}.in-days-fields{grid-template-columns:minmax(0,1fr);gap:0;text-align:center}.resulting-end-date{font-size:11px;color:var(--wkly-muted-color);height:1.4em;margin-bottom:4px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.time-fields{display:grid;grid-template-columns:1fr 1fr 52px;grid-gap:8px;gap:8px;padding:14px 0;border-top:1px solid var(--wkly-border-color)}.time-fields.seconds{grid-template-columns:1fr 1fr 1fr 48px}.period{display:flex;flex-direction:column;justify-content:center;gap:2px;padding-top:1.25em}.period button{font-size:.85em}.period [aria-pressed=true]{background:var(--wkly-range-color);box-shadow:inset 0 0 0 1px var(--wkly-accent-color);font-weight:700}.validation{color:var(--wkly-error-color);font-size:.85em}.validation p{margin:.5em .85em}footer{padding:12px;border-top:1px solid var(--wkly-border-color)}.confirm{background:var(--wkly-accent-color);color:var(--wkly-accent-text-color);width:100%;font-weight:650}.confirm:hover:not(:disabled){background:var(--wkly-accent-color-alternate)}@media (forced-colors: active){.day.selected{outline:2px solid Highlight}.range{border-bottom:2px solid Highlight}.today{outline:1px dashed CanvasText}}@media (prefers-reduced-motion: reduce){*{scroll-behavior:auto!important;animation:none!important}}\n"] }]
1277
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
1278
+ type: Inject,
1279
+ args: [LOCALE_ID]
1280
+ }] }, { type: undefined, decorators: [{
1281
+ type: Inject,
1282
+ args: [WKLY_CONFIG]
1283
+ }] }, { type: undefined, decorators: [{
1284
+ type: Inject,
1285
+ args: [WKLY_CLOCK]
1286
+ }] }, { type: undefined, decorators: [{
1287
+ type: Inject,
1288
+ args: [WKLY_LOCALIZATION]
1289
+ }] }, { type: undefined, decorators: [{
1290
+ type: Inject,
1291
+ args: [WKLY_TRANSLATIONS]
1292
+ }] }, { type: Object, decorators: [{
1293
+ type: Inject,
1294
+ args: [PLATFORM_ID]
1295
+ }] }, { type: i0.ElementRef }, { type: i0.ChangeDetectorRef }]; }, propDecorators: { scroller: [{
1296
+ type: ViewChild,
1297
+ args: ["scroller"]
1298
+ }] } });
1299
+
1300
+ /** Native-dialog factory. Browser resources are allocated only by open(). */
1301
+ class WklyDateTimePickerDialogService {
1302
+ constructor(resolver, injector, app, document, platform) {
1303
+ this.resolver = resolver;
1304
+ this.injector = injector;
1305
+ this.app = app;
1306
+ this.document = document;
1307
+ this.platform = platform;
1308
+ }
1309
+ open(trigger, onCancel, backdrop = true, injector) {
1310
+ if (!isPlatformBrowser(this.platform))
1311
+ throw new Error("Picker presentations can only open in a browser");
1312
+ const dialog = this.document.createElement("dialog");
1313
+ dialog.setAttribute("aria-label", "Date and time picker");
1314
+ Object.assign(dialog.style, {
1315
+ padding: "0",
1316
+ border: "0",
1317
+ borderRadius: "14px",
1318
+ width: "min(390px, 100vw)",
1319
+ maxWidth: "100vw",
1320
+ maxHeight: "94vh",
1321
+ background: "transparent",
1322
+ });
1323
+ const component = this.resolver
1324
+ .resolveComponentFactory(WklyDateTimePickerComponent)
1325
+ .create(injector || this.injector);
1326
+ component.instance.presentation = "transient";
1327
+ dialog.appendChild(component.location.nativeElement);
1328
+ this.document.body.appendChild(dialog);
1329
+ this.app.attachView(component.hostView);
1330
+ const cancel = (event) => {
1331
+ event.preventDefault();
1332
+ onCancel("escape");
1333
+ };
1334
+ const click = (event) => {
1335
+ if (backdrop && event.target === dialog) {
1336
+ const r = dialog.getBoundingClientRect();
1337
+ if (event.clientX < r.left ||
1338
+ event.clientX > r.right ||
1339
+ event.clientY < r.top ||
1340
+ event.clientY > r.bottom)
1341
+ onCancel("backdrop");
1342
+ }
1343
+ };
1344
+ const keydown = (event) => {
1345
+ if (event.key !== "Tab")
1346
+ return;
1347
+ const controls = Array.from(dialog.querySelectorAll('button:not(:disabled),input:not(:disabled),[tabindex="0"]')).filter((el) => el.tabIndex >= 0 &&
1348
+ el.getClientRects().length &&
1349
+ getComputedStyle(el).visibility !== "hidden");
1350
+ const first = controls[0], last = controls[controls.length - 1];
1351
+ if (first &&
1352
+ (event.shiftKey
1353
+ ? this.document.activeElement === first
1354
+ : this.document.activeElement === last)) {
1355
+ event.preventDefault();
1356
+ (event.shiftKey ? last : first).focus();
1357
+ }
1358
+ };
1359
+ dialog.addEventListener("cancel", cancel);
1360
+ dialog.addEventListener("click", click);
1361
+ dialog.addEventListener("keydown", keydown);
1362
+ dialog.showModal();
1363
+ return {
1364
+ component,
1365
+ destroy: () => {
1366
+ dialog.removeEventListener("cancel", cancel);
1367
+ dialog.removeEventListener("click", click);
1368
+ dialog.removeEventListener("keydown", keydown);
1369
+ dialog.close();
1370
+ this.app.detachView(component.hostView);
1371
+ component.destroy();
1372
+ dialog.remove();
1373
+ trigger.focus();
1374
+ },
1375
+ };
1376
+ }
1377
+ }
1378
+ WklyDateTimePickerDialogService.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerDialogService, deps: [{ token: i0.ComponentFactoryResolver }, { token: i0.Injector }, { token: i0.ApplicationRef }, { token: DOCUMENT }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Injectable });
1379
+ WklyDateTimePickerDialogService.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerDialogService, providedIn: "root" });
1380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerDialogService, decorators: [{
1381
+ type: Injectable,
1382
+ args: [{ providedIn: "root" }]
1383
+ }], ctorParameters: function () { return [{ type: i0.ComponentFactoryResolver }, { type: i0.Injector }, { type: i0.ApplicationRef }, { type: Document, decorators: [{
1384
+ type: Inject,
1385
+ args: [DOCUMENT]
1386
+ }] }, { type: Object, decorators: [{
1387
+ type: Inject,
1388
+ args: [PLATFORM_ID]
1389
+ }] }]; } });
1390
+ /** Shared trigger lifecycle; optional presentation packages extend this class. */
1391
+ class WklyTriggerBase extends WklyPickerInputs {
1392
+ constructor(element) {
1393
+ super();
1394
+ this.element = element;
1395
+ this.ref = null;
1396
+ this.subscriptions = [];
1397
+ this.errors = [];
1398
+ this.change = () => { };
1399
+ this.touched = () => { };
1400
+ this.validation = () => { };
1401
+ }
1402
+ open() {
1403
+ if (this[WklyPickerInputsPropertyKeys.Disabled] || this.ref)
1404
+ return;
1405
+ this.ref = this.create();
1406
+ const picker = this.ref.component.instance;
1407
+ this.copy();
1408
+ this.subscriptions = [
1409
+ picker[WklyPickerOutputsPropertyKeys.ValueChange].subscribe((value) => {
1410
+ this[WklyPickerInputsPropertyKeys.Value] = value;
1411
+ this.change(value);
1412
+ this[WklyPickerOutputsPropertyKeys.ValueChange].emit(value);
1413
+ this.display();
1414
+ }),
1415
+ picker[WklyPickerOutputsPropertyKeys.ValidationChange].subscribe((errors) => {
1416
+ this.errors = errors;
1417
+ this[WklyPickerOutputsPropertyKeys.ValidationChange].emit(errors);
1418
+ this.validation();
1419
+ }),
1420
+ picker[WklyPickerOutputsPropertyKeys.Closed].subscribe((reason) => this.close(reason)),
1421
+ picker[WklyPickerOutputsPropertyKeys.ViewportChange].subscribe((value) => this[WklyPickerOutputsPropertyKeys.ViewportChange].emit(value)),
1422
+ picker[WklyPickerOutputsPropertyKeys.ViewModeChange].subscribe((value) => this[WklyPickerOutputsPropertyKeys.ViewModeChange].emit(value)),
1423
+ ];
1424
+ this.ref.component.changeDetectorRef.detectChanges();
1425
+ picker.focusDay();
1426
+ this[WklyPickerOutputsPropertyKeys.Opened].emit();
1427
+ }
1428
+ key(event) {
1429
+ if (event.key === "Enter" ||
1430
+ event.key === " " ||
1431
+ event.key === "ArrowDown") {
1432
+ event.preventDefault();
1433
+ this.open();
1434
+ }
1435
+ }
1436
+ blur() {
1437
+ this.touched();
1438
+ }
1439
+ close(reason = "programmatic") {
1440
+ if (!this.ref)
1441
+ return;
1442
+ const ref = this.ref;
1443
+ this.ref = null;
1444
+ this.subscriptions.forEach((s) => s.unsubscribe());
1445
+ this.subscriptions = [];
1446
+ ref.destroy();
1447
+ this.touched();
1448
+ this[WklyPickerOutputsPropertyKeys.Closed].emit(reason);
1449
+ }
1450
+ ngOnChanges() {
1451
+ [
1452
+ WklyPickerInputsPropertyKeys.ShowSeconds,
1453
+ WklyPickerInputsPropertyKeys.AllowRangeAcrossDisabled,
1454
+ WklyPickerInputsPropertyKeys.Required,
1455
+ WklyPickerInputsPropertyKeys.Disabled,
1456
+ WklyPickerInputsPropertyKeys.CloseOnBackdrop,
1457
+ ].forEach((key) => (this[key] = coerceBoolean(this[key])));
1458
+ this.checkValue();
1459
+ this.display();
1460
+ if (this.ref) {
1461
+ this.copy();
1462
+ this.ref.component.instance.ngOnChanges({
1463
+ [WklyPickerInputsPropertyKeys.Value]: true,
1464
+ });
1465
+ this.ref.component.changeDetectorRef.detectChanges();
1466
+ }
1467
+ }
1468
+ ngOnDestroy() {
1469
+ this.close();
1470
+ }
1471
+ copy() {
1472
+ if (this.ref)
1473
+ for (const name of INPUT_NAMES)
1474
+ this.ref.component.instance[name] = this[name];
1475
+ }
1476
+ display() {
1477
+ const host = this.element.nativeElement;
1478
+ if (host.tagName === "INPUT") {
1479
+ host.readOnly = true;
1480
+ const value = this[WklyPickerInputsPropertyKeys.Value];
1481
+ host.value =
1482
+ value === null
1483
+ ? ""
1484
+ : typeof value === "string"
1485
+ ? value
1486
+ : value.join(" — ");
1487
+ host.disabled = this[WklyPickerInputsPropertyKeys.Disabled];
1488
+ host.setAttribute("aria-haspopup", "dialog");
1489
+ }
1490
+ }
1491
+ checkValue() {
1492
+ this.errors = validateSelection(this[WklyPickerInputsPropertyKeys.Value], this, this[WklyPickerInputsPropertyKeys.CalendarAdapter] ||
1493
+ new WklyGregorianCalendarAdapter(this[WklyPickerInputsPropertyKeys.Locale] || "en-US"));
1494
+ this[WklyPickerOutputsPropertyKeys.ValidationChange].emit(this.errors);
1495
+ this.validation();
1496
+ }
1497
+ writeValue(value) {
1498
+ this[WklyPickerInputsPropertyKeys.Value] = value;
1499
+ this.checkValue();
1500
+ this.display();
1501
+ if (this.ref)
1502
+ this.ref.component.instance.writeValue(value);
1503
+ }
1504
+ registerOnChange(fn) {
1505
+ this.change = fn;
1506
+ }
1507
+ registerOnTouched(fn) {
1508
+ this.touched = fn;
1509
+ }
1510
+ setDisabledState(value) {
1511
+ this[WklyPickerInputsPropertyKeys.Disabled] = value;
1512
+ this.display();
1513
+ if (this.ref)
1514
+ this.ref.component.instance.setDisabledState(value);
1515
+ }
1516
+ validate() {
1517
+ return this.errors.length ? { wkly: this.errors } : null;
1518
+ }
1519
+ registerOnValidatorChange(fn) {
1520
+ this.validation = fn;
1521
+ }
1522
+ scrollToEpochDay(day, options) {
1523
+ this.open();
1524
+ this.ref?.component.instance.scrollToEpochDay(day, options);
1525
+ }
1526
+ scrollToAbsoluteWeek(week, options) {
1527
+ this.open();
1528
+ this.ref?.component.instance.scrollToAbsoluteWeek(week, options);
1529
+ }
1530
+ scrollToCalendarDate(date, options) {
1531
+ this.open();
1532
+ this.ref?.component.instance.scrollToCalendarDate(date, options);
1533
+ }
1534
+ scrollToValue(value, options) {
1535
+ this.open();
1536
+ this.ref?.component.instance.scrollToValue(value, options);
1537
+ }
1538
+ }
1539
+ WklyTriggerBase.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyTriggerBase, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive });
1540
+ WklyTriggerBase.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: WklyTriggerBase, host: { listeners: { "click": "open()", "keydown": "key($event)", "blur": "blur()" } }, usesInheritance: true, usesOnChanges: true, ngImport: i0 });
1541
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyTriggerBase, decorators: [{
1542
+ type: Directive
1543
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }]; }, propDecorators: { open: [{
1544
+ type: HostListener,
1545
+ args: ["click"]
1546
+ }], key: [{
1547
+ type: HostListener,
1548
+ args: ["keydown", ["$event"]]
1549
+ }], blur: [{
1550
+ type: HostListener,
1551
+ args: ["blur"]
1552
+ }] } });
1553
+ class WklyDateTimePickerDialogDirective extends WklyTriggerBase {
1554
+ constructor(element, service, triggerInjector) {
1555
+ super(element);
1556
+ this.service = service;
1557
+ this.triggerInjector = triggerInjector;
1558
+ }
1559
+ create() {
1560
+ return this.service.open(this.element.nativeElement, (reason) => this.close(reason), this[WklyPickerInputsPropertyKeys.CloseOnBackdrop], this.triggerInjector);
1561
+ }
1562
+ }
1563
+ WklyDateTimePickerDialogDirective.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerDialogDirective, deps: [{ token: i0.ElementRef }, { token: WklyDateTimePickerDialogService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.Directive });
1564
+ WklyDateTimePickerDialogDirective.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "13.4.0", type: WklyDateTimePickerDialogDirective, selector: "[wklyDateTimePickerDialog]", providers: [
1565
+ {
1566
+ provide: NG_VALUE_ACCESSOR,
1567
+ useExisting: forwardRef(() => WklyDateTimePickerDialogDirective),
1568
+ multi: true,
1569
+ },
1570
+ {
1571
+ provide: NG_VALIDATORS,
1572
+ useExisting: forwardRef(() => WklyDateTimePickerDialogDirective),
1573
+ multi: true,
1574
+ },
1575
+ ], exportAs: ["wklyDialog"], usesInheritance: true, ngImport: i0 });
1576
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerDialogDirective, decorators: [{
1577
+ type: Directive,
1578
+ args: [{
1579
+ selector: "[wklyDateTimePickerDialog]",
1580
+ exportAs: "wklyDialog",
1581
+ providers: [
1582
+ {
1583
+ provide: NG_VALUE_ACCESSOR,
1584
+ useExisting: forwardRef(() => WklyDateTimePickerDialogDirective),
1585
+ multi: true,
1586
+ },
1587
+ {
1588
+ provide: NG_VALIDATORS,
1589
+ useExisting: forwardRef(() => WklyDateTimePickerDialogDirective),
1590
+ multi: true,
1591
+ },
1592
+ ],
1593
+ }]
1594
+ }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: WklyDateTimePickerDialogService }, { type: i0.Injector }]; } });
1595
+
1596
+ class WklyDateTimePickerModule {
1597
+ }
1598
+ WklyDateTimePickerModule.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
1599
+ WklyDateTimePickerModule.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerModule, declarations: [WklyDateTimePickerComponent,
1600
+ WklyDateTimePickerDialogDirective,
1601
+ WklyFieldComponent], imports: [CommonModule], exports: [WklyDateTimePickerComponent, WklyDateTimePickerDialogDirective] });
1602
+ WklyDateTimePickerModule.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerModule, imports: [[CommonModule]] });
1603
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "13.4.0", ngImport: i0, type: WklyDateTimePickerModule, decorators: [{
1604
+ type: NgModule,
1605
+ args: [{
1606
+ imports: [CommonModule],
1607
+ declarations: [
1608
+ WklyDateTimePickerComponent,
1609
+ WklyDateTimePickerDialogDirective,
1610
+ WklyFieldComponent,
1611
+ ],
1612
+ entryComponents: [WklyDateTimePickerComponent],
1613
+ exports: [WklyDateTimePickerComponent, WklyDateTimePickerDialogDirective],
1614
+ }]
1615
+ }] });
1616
+
1617
+ /**
1618
+ * Generated bundle index. Do not edit.
1619
+ */
1620
+
1621
+ export { WKLY_CLOCK, WKLY_CONFIG, WKLY_LOCALIZATION, WKLY_TRANSLATIONS, WklyDateTimePickerComponent, WklyDateTimePickerDialogDirective, WklyDateTimePickerDialogService, WklyDateTimePickerModule, WklyFieldComponent, WklyPickerInputs, WklyTriggerBase };
1622
+ //# sourceMappingURL=wkly-datetime-picker.mjs.map