@tzslot/angular 0.1.0-beta.0 → 1.1.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.
@@ -1,9 +1,9 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, input, model, computed, signal, inject, ElementRef, effect, untracked, DestroyRef, forwardRef, ChangeDetectionStrategy, Component, viewChild, output } from '@angular/core';
2
+ import { InjectionToken, inject, input, model, computed, signal, ElementRef, effect, untracked, DestroyRef, forwardRef, ChangeDetectionStrategy, Component, viewChild, output } from '@angular/core';
3
3
  import { NG_VALUE_ACCESSOR } from '@angular/forms';
4
- import { EN, getSlotChoices, createTimeSlots, createCalendar, createDateField, createDateRange, createDateTimeRange, createDailyRange, createMultiDate } from '@tzslot/dom';
4
+ import { EN, getSlotChoices, createTimeSlots, createCalendar, createDateField, createDateTimeField, createRangeField, createDateRange, createDateTimeRange, createDailyRange, createMultiDate } from '@tzslot/dom';
5
5
  export { EN, FR } from '@tzslot/dom';
6
- import { Temporal, toPlainDate, fromPlainDate } from '@tzslot/core';
6
+ import { Temporal, toInstant, fromInstant, toPlainDate, fromPlainDate } from '@tzslot/core';
7
7
 
8
8
  const TZSLOT_MESSAGES = new InjectionToken('tzslot.messages', {
9
9
  providedIn: 'root',
@@ -14,6 +14,24 @@ function provideTzslotMessages(messages) {
14
14
  return { provide: TZSLOT_MESSAGES, useValue: messages };
15
15
  }
16
16
 
17
+ const TZSLOT_DEFAULTS = new InjectionToken('tzslot.defaults', {
18
+ providedIn: 'root',
19
+ factory: () => ({}),
20
+ });
21
+ /**
22
+ * `providers: [provideTzslot({ valueAs: 'utc', timeZone: 'Europe/Paris' })]`
23
+ *
24
+ * In an application: `bootstrapApplication(App, { providers: [provideTzslot({ … })] })`.
25
+ */
26
+ function provideTzslot(defaults) {
27
+ const providers = [
28
+ { provide: TZSLOT_DEFAULTS, useValue: defaults },
29
+ ];
30
+ if (defaults.messages)
31
+ providers.push({ provide: TZSLOT_MESSAGES, useValue: defaults.messages });
32
+ return providers;
33
+ }
34
+
17
35
  /**
18
36
  * `<tz-time-slots>` — the slot list from @tzslot/dom, spoken in Angular.
19
37
  *
@@ -22,10 +40,22 @@ function provideTzslotMessages(messages) {
22
40
  */
23
41
  class TimeSlotPicker {
24
42
  constructor() {
43
+ /** Set once for the application with provideTzslot(); a binding still wins. */
44
+ this.defaults = inject(TZSLOT_DEFAULTS);
25
45
  /** The day to list, as a PlainDate or an ISO date string. */
46
+ /**
47
+ * What the form control holds. `'utc'` gives an ISO string; the default
48
+ * gives an Instant.
49
+ */
50
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
26
51
  this.date = input.required(...(ngDevMode ? [{ debugName: "date" }] : /* istanbul ignore next */ []));
27
- /** An IANA identifier — 'Europe/Paris', not an offset. Offsets change twice a year. */
28
- this.timeZone = input.required(...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
52
+ /**
53
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
54
+ * is the zone provideTzslot() settled for the application, and only when
55
+ * nothing was settled anywhere does it fall back to the browser's — which
56
+ * is a guess, and the one thing this library exists not to do silently.
57
+ */
58
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
29
59
  this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
30
60
  /** The working day. Slots outside these bounds are not produced at all. */
31
61
  this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
@@ -94,11 +124,12 @@ class TimeSlotPicker {
94
124
  clear() {
95
125
  this.slots.clear();
96
126
  }
127
+ /** Typed `unknown`: a form holds what the application put there. */
97
128
  writeValue(value) {
98
- this.value.set(value ?? null);
129
+ this.value.set(value === null || value === undefined ? null : toInstant(value));
99
130
  }
100
131
  registerOnChange(fn) {
101
- this.onChange = fn;
132
+ this.onChange = (next) => fn(fromInstant(next, this.valueAs()));
102
133
  }
103
134
  registerOnTouched(fn) {
104
135
  this.onTouched = fn;
@@ -107,7 +138,7 @@ class TimeSlotPicker {
107
138
  this.formDisabled.set(isDisabled);
108
139
  }
109
140
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: TimeSlotPicker, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
110
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: TimeSlotPicker, isStandalone: true, selector: "tz-time-slots", inputs: { date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: true, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: true, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, skipNonExistent: { classPropertyName: "skipNonExistent", publicName: "skipNonExistent", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, missingLabel: { classPropertyName: "missingLabel", publicName: "missingLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
141
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: TimeSlotPicker, isStandalone: true, selector: "tz-time-slots", inputs: { valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: true, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: false, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, isDisabled: { classPropertyName: "isDisabled", publicName: "isDisabled", isSignal: true, isRequired: false, transformFunction: null }, skipNonExistent: { classPropertyName: "skipNonExistent", publicName: "skipNonExistent", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, missingLabel: { classPropertyName: "missingLabel", publicName: "missingLabel", isSignal: true, isRequired: false, transformFunction: null }, emptyLabel: { classPropertyName: "emptyLabel", publicName: "emptyLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
111
142
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => TimeSlotPicker), multi: true },
112
143
  ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
113
144
  }
@@ -122,7 +153,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
122
153
  ],
123
154
  template: '',
124
155
  }]
125
- }], ctorParameters: () => [], propDecorators: { date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: true }] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: true }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDisabled", required: false }] }], skipNonExistent: [{ type: i0.Input, args: [{ isSignal: true, alias: "skipNonExistent", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], missingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "missingLabel", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }] } });
156
+ }], ctorParameters: () => [], propDecorators: { valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: true }] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: false }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], isDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDisabled", required: false }] }], skipNonExistent: [{ type: i0.Input, args: [{ isSignal: true, alias: "skipNonExistent", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], missingLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "missingLabel", required: false }] }], emptyLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "emptyLabel", required: false }] }] } });
157
+
158
+ /** Whatever the form holds, as two moments. */
159
+ function pairIn(value) {
160
+ if (value === null || value === undefined)
161
+ return { start: null, end: null };
162
+ const given = value;
163
+ const one = (at) => at === null || at === undefined ? null : toInstant(at);
164
+ return { start: one(given.start), end: one(given.end) };
165
+ }
166
+ /** And back out, in the shape the application asked for. */
167
+ function pairOut(pair, shape, extra) {
168
+ return {
169
+ ...extra,
170
+ start: fromInstant(pair.start, shape),
171
+ end: fromInstant(pair.end, shape),
172
+ };
173
+ }
126
174
 
127
175
  /**
128
176
  * `<tz-calendar>` — the calendar from @tzslot/dom, spoken in Angular.
@@ -133,12 +181,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
133
181
  */
134
182
  class Calendar {
135
183
  constructor() {
184
+ /** Set once for the application with provideTzslot(); a binding still wins. */
185
+ this.defaults = inject(TZSLOT_DEFAULTS);
136
186
  /** The selected day. Two-way: `[(value)]`. */
137
187
  this.value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
138
188
  /** Monday by default, as ISO-8601 numbers the week. */
139
- this.firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
189
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
190
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
140
191
  /** A BCP-47 tag for the month and weekday names. Defaults to the browser's. */
141
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
192
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
142
193
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
143
194
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
144
195
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -147,13 +198,13 @@ class Calendar {
147
198
  * existing FormControl<Date> keep working untouched, which is the whole of a
148
199
  * flatpickr migration on most screens.
149
200
  */
150
- this.valueAs = input('temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
201
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
151
202
  /**
152
203
  * The zone used to turn a Date into a calendar day and back. Only consulted
153
204
  * when valueAs is 'date': which day an instant falls on depends on where you
154
205
  * are standing, so it is explicit rather than guessed.
155
206
  */
156
- this.valueTimeZone = input(Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
207
+ this.valueTimeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
157
208
  /** Rules out individual days inside the range: closures, weekends, full days. */
158
209
  this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
159
210
  /** Today, injectable so a test does not depend on the day it runs. */
@@ -167,6 +218,8 @@ class Calendar {
167
218
  this.minView = input('days', ...(ngDevMode ? [{ debugName: "minView" }] : /* istanbul ignore next */ []));
168
219
  /** Adds to each day: a price, places left, a class, a reason to rule it out. */
169
220
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
221
+ /** A column of ISO week numbers down the left. */
222
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
170
223
  /** Buttons under the grid: `['today', 'clear']`. None by default. */
171
224
  this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
172
225
  this.host = inject(ElementRef).nativeElement;
@@ -187,6 +240,7 @@ class Calendar {
187
240
  today: this.today(),
188
241
  renderCell: this.renderCell(),
189
242
  buttons: this.buttons(),
243
+ weekNumbers: this.weekNumbers(),
190
244
  messages: this.messages,
191
245
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
192
246
  /**
@@ -255,7 +309,7 @@ class Calendar {
255
309
  this.formDisabled.set(isDisabled);
256
310
  }
257
311
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: Calendar, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
258
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: Calendar, isStandalone: true, selector: "tz-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, minView: { classPropertyName: "minView", publicName: "minView", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", view: "viewChange" }, providers: [
312
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: Calendar, isStandalone: true, selector: "tz-calendar", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, minView: { classPropertyName: "minView", publicName: "minView", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", view: "viewChange" }, providers: [
259
313
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => Calendar), multi: true },
260
314
  ], viewQueries: [{ propertyName: "prevSlot", first: true, predicate: ["prev"], descendants: true, isSignal: true }, { propertyName: "nextSlot", first: true, predicate: ["next"], descendants: true, isSignal: true }], ngImport: i0, template: `
261
315
  <span #prev hidden><ng-content select="[tzPrev]" /></span>
@@ -278,7 +332,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
278
332
  <span #next hidden><ng-content select="[tzNext]" /></span>
279
333
  `,
280
334
  }]
281
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], minView: [{ type: i0.Input, args: [{ isSignal: true, alias: "minView", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
335
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], minView: [{ type: i0.Input, args: [{ isSignal: true, alias: "minView", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
282
336
 
283
337
  /**
284
338
  * `<tz-date-field>` — the field from @tzslot/dom, spoken in Angular.
@@ -290,12 +344,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
290
344
  */
291
345
  class DateField {
292
346
  constructor() {
347
+ /** Set once for the application with provideTzslot(); a binding still wins. */
348
+ this.defaults = inject(TZSLOT_DEFAULTS);
293
349
  this.value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
294
350
  this.mode = input('popup', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
295
351
  this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
296
352
  this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
297
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
298
- this.firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
353
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
354
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
355
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
299
356
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
300
357
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
301
358
  this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
@@ -305,17 +362,19 @@ class DateField {
305
362
  * existing FormControl<Date> keep working untouched, which is the whole of a
306
363
  * flatpickr migration on most screens.
307
364
  */
308
- this.valueAs = input('temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
365
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
309
366
  /**
310
367
  * The zone used to turn a Date into a calendar day and back. Only consulted
311
368
  * when valueAs is 'date': which day an instant falls on depends on where you
312
369
  * are standing, so it is explicit rather than guessed.
313
370
  */
314
- this.valueTimeZone = input(Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
371
+ this.valueTimeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
315
372
  /** How the chosen date is written in the field. Defaults to the locale's medium form. */
316
373
  this.displayWith = input(undefined, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
317
374
  /** Passed to the calendar in the panel. */
318
375
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
376
+ /** A column of ISO week numbers down the left. */
377
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
319
378
  /** Under the panel's grid: `['today', 'clear']`. Choosing either closes it. */
320
379
  this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
321
380
  this.opened = output();
@@ -323,6 +382,8 @@ class DateField {
323
382
  /** Whether the panel is showing. Readable from a ViewChild. */
324
383
  this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
325
384
  this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
385
+ /** Set while the component is being destroyed, so no output fires after it. */
386
+ this.gone = false;
326
387
  this.host = inject(ElementRef).nativeElement;
327
388
  this.messages = inject(TZSLOT_MESSAGES);
328
389
  this.iconSlot = viewChild.required('icon');
@@ -340,6 +401,7 @@ class DateField {
340
401
  displayWith: this.displayWith(),
341
402
  renderCell: this.renderCell(),
342
403
  buttons: this.buttons(),
404
+ weekNumbers: this.weekNumbers(),
343
405
  messages: this.messages,
344
406
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
345
407
  this.field = createDateField(this.host, {
@@ -351,11 +413,15 @@ class DateField {
351
413
  onOpen: () => {
352
414
  this.isOpen.set(true);
353
415
  this.onTouched();
354
- this.opened.emit();
416
+ if (!this.gone)
417
+ this.opened.emit();
355
418
  },
356
419
  onClose: () => {
357
420
  this.isOpen.set(false);
358
- this.closed.emit();
421
+ // Destroying the component closes its panel; an output that fires then
422
+ // is an emit on a destroyed ref (NG0953), and nothing is listening.
423
+ if (!this.gone)
424
+ this.closed.emit();
359
425
  },
360
426
  });
361
427
  // ── ControlValueAccessor ────────────────────────────────────
@@ -369,7 +435,10 @@ class DateField {
369
435
  const settings = this.settings();
370
436
  untracked(() => this.field.update(settings));
371
437
  });
372
- inject(DestroyRef).onDestroy(() => this.field.destroy());
438
+ inject(DestroyRef).onDestroy(() => {
439
+ this.gone = true;
440
+ this.field.destroy();
441
+ });
373
442
  }
374
443
  ngAfterViewInit() {
375
444
  const slot = this.iconSlot().nativeElement;
@@ -410,7 +479,7 @@ class DateField {
410
479
  this.formDisabled.set(isDisabled);
411
480
  }
412
481
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
413
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: DateField, isStandalone: true, selector: "tz-date-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, providers: [
482
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: DateField, isStandalone: true, selector: "tz-date-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, providers: [
414
483
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateField), multi: true },
415
484
  ], viewQueries: [{ propertyName: "iconSlot", first: true, predicate: ["icon"], descendants: true, isSignal: true }], ngImport: i0, template: `<span #icon hidden><ng-content select="[tzIcon]" /></span>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
416
485
  }
@@ -425,15 +494,494 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
425
494
  ],
426
495
  template: `<span #icon hidden><ng-content select="[tzIcon]" /></span>`,
427
496
  }]
428
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], iconSlot: [{ type: i0.ViewChild, args: ['icon', { isSignal: true }] }] } });
497
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], iconSlot: [{ type: i0.ViewChild, args: ['icon', { isSignal: true }] }] } });
498
+
499
+ /**
500
+ * `<tz-datetime-field>` — a field that opens a calendar and a time, from
501
+ * @tzslot/dom, spoken in Angular.
502
+ *
503
+ * Its value is an Instant, so it says which moment was meant even when the
504
+ * clock face does not: a time the zone skips is moved on and explained, and
505
+ * one that happens twice is offered by its two offsets rather than guessed.
506
+ */
507
+ class DateTimeField {
508
+ constructor() {
509
+ /** Set once for the application with provideTzslot(); a binding still wins. */
510
+ this.defaults = inject(TZSLOT_DEFAULTS);
511
+ this.value = model(null, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
512
+ /**
513
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
514
+ * is the zone provideTzslot() settled for the application, and only when
515
+ * nothing was settled anywhere does it fall back to the browser's — which
516
+ * is a guess, and the one thing this library exists not to do silently.
517
+ */
518
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
519
+ this.mode = input('popup', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
520
+ this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
521
+ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
522
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
523
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
524
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
525
+ this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
526
+ this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
527
+ this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
528
+ /** 'input' (default) for a compact time field, 'list' for the day's times. */
529
+ /**
530
+ * Whether a time is asked for at all. False leaves a field that chooses a
531
+ * day and holds the moment it starts.
532
+ */
533
+ this.showTime = input(true, ...(ngDevMode ? [{ debugName: "showTime" }] : /* istanbul ignore next */ []));
534
+ this.timeLayout = input('input', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
535
+ /**
536
+ * Move a typed time to the nearest mark of this grid — 15 for quarter-hour
537
+ * appointments, ties upward. Off by default: a screen that accepts any
538
+ * minute must not have them quietly moved.
539
+ */
540
+ this.snapMinutes = input(null, ...(ngDevMode ? [{ debugName: "snapMinutes" }] : /* istanbul ignore next */ []));
541
+ /**
542
+ * Arrows beside the field that step the chosen moment without opening the
543
+ * panel: `{ hours: 1 }`, `{ days: 1 }`. `false` — the default — draws none.
544
+ * Counted on the zone's clocks, so a day is 23 or 25 hours when they change.
545
+ */
546
+ this.shift = input(false, ...(ngDevMode ? [{ debugName: "shift" }] : /* istanbul ignore next */ []));
547
+ /** Whether the step sits between the arrows, to be read and pressed. */
548
+ this.showStep = input(true, ...(ngDevMode ? [{ debugName: "showStep" }] : /* istanbul ignore next */ []));
549
+ this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
550
+ /** With timeLayout 'select': minutes between the options. Every minute by default. */
551
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
552
+ this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
553
+ this.maxTime = input(undefined, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
554
+ /** Only with timeLayout 'list': rules out slots while still showing them. */
555
+ this.isSlotDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isSlotDisabled" }] : /* istanbul ignore next */ []));
556
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
557
+ /** The time a newly chosen day starts at. Midnight by default. */
558
+ this.defaultTime = input('00:00', ...(ngDevMode ? [{ debugName: "defaultTime" }] : /* istanbul ignore next */ []));
559
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
560
+ /** The text can be typed as well as chosen. On by default. */
561
+ this.editable = input(true, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
562
+ /** Separators appear as the figures are typed, like a card number. On by default. */
563
+ this.mask = input(true, ...(ngDevMode ? [{ debugName: "mask" }] : /* istanbul ignore next */ []));
564
+ /** A pattern — `yyyy-MM-dd HH:mm` — when the shape matters more than the reader. */
565
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
566
+ /** Used when the field is not typable and no pattern is given. */
567
+ this.dateStyle = input('medium', ...(ngDevMode ? [{ debugName: "dateStyle" }] : /* istanbul ignore next */ []));
568
+ this.timeStyle = input('short', ...(ngDevMode ? [{ debugName: "timeStyle" }] : /* istanbul ignore next */ []));
569
+ /** The last word on the text. Given both, this one wins. */
570
+ this.displayWith = input(undefined, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
571
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
572
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
573
+ /** A column of ISO week numbers down the left. */
574
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
575
+ this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
576
+ /** What the form control holds: a Temporal Instant, a Date, or an ISO string. */
577
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
578
+ this.opened = output();
579
+ this.closed = output();
580
+ /** Whether the panel is showing. Readable from a ViewChild. */
581
+ this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
582
+ this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
583
+ /** Set while the component is being destroyed, so no output fires after it. */
584
+ this.gone = false;
585
+ this.host = inject(ElementRef).nativeElement;
586
+ this.messages = inject(TZSLOT_MESSAGES);
587
+ this.iconSlot = viewChild.required('icon');
588
+ this.settings = computed(() => ({
589
+ value: this.value(),
590
+ timeZone: this.timeZone(),
591
+ mode: this.mode(),
592
+ placeholder: this.placeholder(),
593
+ ariaLabel: this.ariaLabel(),
594
+ locale: this.locale(),
595
+ firstDayOfWeek: this.firstDayOfWeek(),
596
+ min: this.min(),
597
+ max: this.max(),
598
+ isDateDisabled: this.isDateDisabled(),
599
+ showTime: this.showTime(),
600
+ timeLayout: this.timeLayout(),
601
+ snapMinutes: this.snapMinutes(),
602
+ shift: this.shift(),
603
+ showStep: this.showStep(),
604
+ stepMinutes: this.stepMinutes(),
605
+ minuteStep: this.minuteStep(),
606
+ minTime: this.minTime(),
607
+ maxTime: this.maxTime(),
608
+ isSlotDisabled: this.isSlotDisabled(),
609
+ hour12: this.hour12(),
610
+ defaultTime: this.defaultTime(),
611
+ disabled: this.disabled() || this.formDisabled(),
612
+ editable: this.editable(),
613
+ mask: this.mask(),
614
+ format: this.format(),
615
+ dateStyle: this.dateStyle(),
616
+ timeStyle: this.timeStyle(),
617
+ displayWith: this.displayWith(),
618
+ today: this.today(),
619
+ renderCell: this.renderCell(),
620
+ buttons: this.buttons(),
621
+ weekNumbers: this.weekNumbers(),
622
+ messages: this.messages,
623
+ }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
624
+ /** Created before the required timeZone is bound; the first change detection fills it in. */
625
+ this.field = createDateTimeField(this.host, {
626
+ messages: this.messages,
627
+ onChange: (value) => {
628
+ this.value.set(value);
629
+ this.onChange(value);
630
+ },
631
+ onOpen: () => {
632
+ this.isOpen.set(true);
633
+ this.onTouched();
634
+ if (!this.gone)
635
+ this.opened.emit();
636
+ },
637
+ onClose: () => {
638
+ this.isOpen.set(false);
639
+ // Destroying the component closes its panel; an output that fires then
640
+ // is an emit on a destroyed ref (NG0953), and nothing is listening.
641
+ if (!this.gone)
642
+ this.closed.emit();
643
+ },
644
+ });
645
+ // ── ControlValueAccessor ────────────────────────────────────
646
+ this.onChange = () => { };
647
+ this.onTouched = () => { };
648
+ effect(() => {
649
+ const settings = this.settings();
650
+ untracked(() => this.field.update(settings));
651
+ });
652
+ inject(DestroyRef).onDestroy(() => {
653
+ this.gone = true;
654
+ this.field.destroy();
655
+ });
656
+ }
657
+ ngAfterViewInit() {
658
+ const slot = this.iconSlot().nativeElement;
659
+ if (Array.from(slot.childNodes).some((n) => n.nodeType === Node.ELEMENT_NODE || n.textContent?.trim())) {
660
+ const fragment = this.host.ownerDocument.createDocumentFragment();
661
+ fragment.append(...Array.from(slot.childNodes));
662
+ this.field.setIcon(fragment);
663
+ }
664
+ }
665
+ toggle() {
666
+ this.field.toggle();
667
+ }
668
+ /** No-op when already open. */
669
+ open() {
670
+ this.field.open();
671
+ }
672
+ close() {
673
+ this.field.close();
674
+ }
675
+ /** Clears the selection and tells any form control about it. */
676
+ clear() {
677
+ this.field.clear();
678
+ }
679
+ writeValue(value) {
680
+ this.value.set(value === null || value === undefined ? null : toInstant(value));
681
+ }
682
+ registerOnChange(fn) {
683
+ this.onChange = (value) => fn(fromInstant(value, this.valueAs()));
684
+ }
685
+ registerOnTouched(fn) {
686
+ this.onTouched = fn;
687
+ }
688
+ setDisabledState(isDisabled) {
689
+ this.formDisabled.set(isDisabled);
690
+ }
691
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateTimeField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
692
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: DateTimeField, isStandalone: true, selector: "tz-datetime-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, timeLayout: { classPropertyName: "timeLayout", publicName: "timeLayout", isSignal: true, isRequired: false, transformFunction: null }, snapMinutes: { classPropertyName: "snapMinutes", publicName: "snapMinutes", isSignal: true, isRequired: false, transformFunction: null }, shift: { classPropertyName: "shift", publicName: "shift", isSignal: true, isRequired: false, transformFunction: null }, showStep: { classPropertyName: "showStep", publicName: "showStep", isSignal: true, isRequired: false, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, isSlotDisabled: { classPropertyName: "isSlotDisabled", publicName: "isSlotDisabled", isSignal: true, isRequired: false, transformFunction: null }, hour12: { classPropertyName: "hour12", publicName: "hour12", isSignal: true, isRequired: false, transformFunction: null }, defaultTime: { classPropertyName: "defaultTime", publicName: "defaultTime", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, dateStyle: { classPropertyName: "dateStyle", publicName: "dateStyle", isSignal: true, isRequired: false, transformFunction: null }, timeStyle: { classPropertyName: "timeStyle", publicName: "timeStyle", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, providers: [
693
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeField), multi: true },
694
+ ], viewQueries: [{ propertyName: "iconSlot", first: true, predicate: ["icon"], descendants: true, isSignal: true }], ngImport: i0, template: `<span #icon hidden><ng-content select="[tzIcon]" /></span>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
695
+ }
696
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateTimeField, decorators: [{
697
+ type: Component,
698
+ args: [{
699
+ selector: 'tz-datetime-field',
700
+ standalone: true,
701
+ changeDetection: ChangeDetectionStrategy.OnPush,
702
+ providers: [
703
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeField), multi: true },
704
+ ],
705
+ template: `<span #icon hidden><ng-content select="[tzIcon]" /></span>`,
706
+ }]
707
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], timeLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLayout", required: false }] }], snapMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapMinutes", required: false }] }], shift: [{ type: i0.Input, args: [{ isSignal: true, alias: "shift", required: false }] }], showStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "showStep", required: false }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], isSlotDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSlotDisabled", required: false }] }], hour12: [{ type: i0.Input, args: [{ isSignal: true, alias: "hour12", required: false }] }], defaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTime", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], dateStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "dateStyle", required: false }] }], timeStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeStyle", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }], iconSlot: [{ type: i0.ViewChild, args: ['icon', { isSignal: true }] }] } });
708
+
709
+ const EMPTY$3 = { start: null, end: null };
710
+ /**
711
+ * `<tz-range-field>` — one field for a period, from @tzslot/dom, spoken in
712
+ * Angular. Named ranges beside the calendar, months side by side, and whole
713
+ * days or moments.
714
+ */
715
+ class RangeField {
716
+ constructor() {
717
+ /** Set once for the application with provideTzslot(); a binding still wins. */
718
+ this.defaults = inject(TZSLOT_DEFAULTS);
719
+ this.value = model(EMPTY$3, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
720
+ /**
721
+ * What the form control holds. `'utc'` gives two ISO strings; the default
722
+ * gives the library's own moments. Settled for a whole application with
723
+ * provideTzslot(), which documents it as applying to every component — and
724
+ * this one did not listen.
725
+ */
726
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
727
+ /**
728
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
729
+ * is the zone provideTzslot() settled for the application, and only when
730
+ * nothing was settled anywhere does it fall back to the browser's — which
731
+ * is a guess, and the one thing this library exists not to do silently.
732
+ */
733
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
734
+ /** Named ranges beside the calendar: the built-in names, or your own. */
735
+ this.presets = input([
736
+ 'thisQuarterHour',
737
+ 'lastHour',
738
+ 'thisHour',
739
+ 'nextHour',
740
+ 'yesterday',
741
+ 'today',
742
+ 'tomorrow',
743
+ 'last7Days',
744
+ 'thisMonth',
745
+ 'thisQuarter',
746
+ ], ...(ngDevMode ? [{ debugName: "presets" }] : /* istanbul ignore next */ []));
747
+ /**
748
+ * Lets a period stop at one end — "from 14 September", "until the 20th".
749
+ * The panel then offers Between / From / Until, and each chosen end can be
750
+ * dropped with the cross beside it. Off by default: a booking form must not
751
+ * accept a period with no end.
752
+ */
753
+ this.openEnded = input(false, ...(ngDevMode ? [{ debugName: "openEnded" }] : /* istanbul ignore next */ []));
754
+ /** A word or two saying what is being chosen — "Travel dates". */
755
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
756
+ /** How an hour is asked for: two menus (default), or figures with arrows. */
757
+ this.timeLayout = input('select', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
758
+ /**
759
+ * Whether the period carries times as well as days — the screen's decision,
760
+ * not the reader's. There is no "all day" switch: on, every chosen day
761
+ * starts at `defaultTimes`.
762
+ */
763
+ this.showTime = input(false, ...(ngDevMode ? [{ debugName: "showTime" }] : /* istanbul ignore next */ []));
764
+ /**
765
+ * The hours a newly chosen day is given: midnight unless the screen knows
766
+ * better — `{ start: '09:00', end: '18:00' }` for a working day. A value
767
+ * handed to the field keeps its own hours.
768
+ */
769
+ this.defaultTimes = input({}, ...(ngDevMode ? [{ debugName: "defaultTimes" }] : /* istanbul ignore next */ []));
770
+ this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
771
+ /**
772
+ * Move a time typed by hand to the nearest mark of this grid — 15 for
773
+ * quarter-hour appointments, ties upward. Off by default.
774
+ */
775
+ this.snapMinutes = input(null, ...(ngDevMode ? [{ debugName: "snapMinutes" }] : /* istanbul ignore next */ []));
776
+ /**
777
+ * How long the period may be, and how short — `'30d'`, `{ hours: 2 }`.
778
+ * Moving one end pushes the other rather than refusing the move.
779
+ */
780
+ this.maxSpan = input(null, ...(ngDevMode ? [{ debugName: "maxSpan" }] : /* istanbul ignore next */ []));
781
+ this.minSpan = input(null, ...(ngDevMode ? [{ debugName: "minSpan" }] : /* istanbul ignore next */ []));
782
+ /** Minutes between the options of the hour menu. Five by default. */
783
+ this.minuteStep = input(5, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
784
+ /** Nothing is reported until Apply is pressed. */
785
+ this.confirm = input(false, ...(ngDevMode ? [{ debugName: "confirm" }] : /* istanbul ignore next */ []));
786
+ /**
787
+ * Arrows that step the whole period without opening the panel.
788
+ *
789
+ * `false` — the default — draws none. `true` draws them and follows what is
790
+ * being chosen: an hour for a period, a day when `singleDay` says it is one
791
+ * date. A duration such as `{ months: 3 }` or `'45mn'` imposes the step; a
792
+ * list offers several and lets the reader pick.
793
+ */
794
+ this.shift = input(false, ...(ngDevMode ? [{ debugName: "shift" }] : /* istanbul ignore next */ []));
795
+ /** Whether the column of shortcuts is drawn. The list itself is kept. */
796
+ this.showPresets = input(true, ...(ngDevMode ? [{ debugName: "showPresets" }] : /* istanbul ignore next */ []));
797
+ /** Whether the step sits between the arrows, to be read and pressed. */
798
+ this.showStep = input(true, ...(ngDevMode ? [{ debugName: "showStep" }] : /* istanbul ignore next */ []));
799
+ /** One field instead of two; a click means that whole day. */
800
+ this.singleDay = input(false, ...(ngDevMode ? [{ debugName: "singleDay" }] : /* istanbul ignore next */ []));
801
+ this.months = input(2, ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
802
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
803
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
804
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
805
+ this.mode = input('popup', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
806
+ this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
807
+ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
808
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
809
+ this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
810
+ this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
811
+ this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
812
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
813
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
814
+ /** The moment the shortcuts shorter than a day are counted from. The clock by default. */
815
+ this.now = input(null, ...(ngDevMode ? [{ debugName: "now" }] : /* istanbul ignore next */ []));
816
+ /**
817
+ * The whole field, or one end of it: `{ end: true }` for a period whose end
818
+ * the screen works out itself. A locked end is read-only rather than
819
+ * disabled — still readable, still reachable by the keyboard.
820
+ */
821
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
822
+ /** A pattern for each end — `yyyy-MM-dd`. */
823
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
824
+ /**
825
+ * What is written above the panel's two fields, and between them. Words by
826
+ * default; `{ start: null, end: null, between: '»' }` for a screen that
827
+ * prefers a mark. A DOM node is taken as it is.
828
+ */
829
+ /**
830
+ * The mark inside the panel's two fields — a calendar by default, `null`
831
+ * for none, or a node of your own.
832
+ */
833
+ this.fieldIcon = input(undefined, ...(ngDevMode ? [{ debugName: "fieldIcon" }] : /* istanbul ignore next */ []));
834
+ this.fieldIconSide = input('start', ...(ngDevMode ? [{ debugName: "fieldIconSide" }] : /* istanbul ignore next */ []));
835
+ this.labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
836
+ /** Separators appear as figures are typed in those fields. */
837
+ this.mask = input(true, ...(ngDevMode ? [{ debugName: "mask" }] : /* istanbul ignore next */ []));
838
+ this.displayWith = input(undefined, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
839
+ this.opened = output();
840
+ this.closed = output();
841
+ /** Whether the panel is showing. Readable from a ViewChild. */
842
+ this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
843
+ this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
844
+ this.gone = false;
845
+ this.messages = inject(TZSLOT_MESSAGES);
846
+ this.settings = computed(() => ({
847
+ value: this.value(),
848
+ timeZone: this.timeZone(),
849
+ presets: this.presets(),
850
+ openEnded: this.openEnded(),
851
+ title: this.title(),
852
+ timeLayout: this.timeLayout(),
853
+ showTime: this.showTime(),
854
+ defaultTimes: this.defaultTimes(),
855
+ stepMinutes: this.stepMinutes(),
856
+ snapMinutes: this.snapMinutes(),
857
+ maxSpan: this.maxSpan(),
858
+ minSpan: this.minSpan(),
859
+ minuteStep: this.minuteStep(),
860
+ confirm: this.confirm(),
861
+ shift: this.shift(),
862
+ showPresets: this.showPresets(),
863
+ showStep: this.showStep(),
864
+ singleDay: this.singleDay(),
865
+ months: this.months(),
866
+ weekNumbers: this.weekNumbers(),
867
+ firstDayOfWeek: this.firstDayOfWeek(),
868
+ mode: this.mode(),
869
+ placeholder: this.placeholder(),
870
+ ariaLabel: this.ariaLabel(),
871
+ locale: this.locale(),
872
+ min: this.min(),
873
+ max: this.max(),
874
+ isDateDisabled: this.isDateDisabled(),
875
+ renderCell: this.renderCell(),
876
+ today: this.today(),
877
+ now: this.now(),
878
+ // A form disabling the control wins over a per-end lock: it means the
879
+ // whole thing is out of play, not that one end of it is.
880
+ disabled: this.formDisabled() ? true : this.disabled(),
881
+ format: this.format(),
882
+ labels: this.labels(),
883
+ fieldIcon: this.fieldIcon(),
884
+ fieldIconSide: this.fieldIconSide(),
885
+ mask: this.mask(),
886
+ displayWith: this.displayWith(),
887
+ messages: this.messages,
888
+ }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
889
+ /** Created before the required timeZone is bound; the first change detection fills it in. */
890
+ this.field = createRangeField(inject(ElementRef).nativeElement, {
891
+ messages: this.messages,
892
+ onChange: (value) => {
893
+ this.value.set(value);
894
+ this.onChange(value);
895
+ this.onTouched();
896
+ },
897
+ onOpen: () => {
898
+ this.isOpen.set(true);
899
+ if (!this.gone)
900
+ this.opened.emit();
901
+ },
902
+ onClose: () => {
903
+ this.isOpen.set(false);
904
+ if (!this.gone)
905
+ this.closed.emit();
906
+ },
907
+ });
908
+ // ── ControlValueAccessor ────────────────────────────────────
909
+ this.onChange = () => { };
910
+ this.onTouched = () => { };
911
+ effect(() => {
912
+ const settings = this.settings();
913
+ untracked(() => this.field.update(settings));
914
+ });
915
+ inject(DestroyRef).onDestroy(() => {
916
+ this.gone = true;
917
+ this.field.destroy();
918
+ });
919
+ }
920
+ open() {
921
+ this.field.open();
922
+ }
923
+ close() {
924
+ this.field.close();
925
+ }
926
+ toggle() {
927
+ this.field.toggle();
928
+ }
929
+ /** Empties the period and tells any form control about it. */
930
+ clear() {
931
+ this.field.clear();
932
+ }
933
+ /**
934
+ * Typed `unknown` because that is what a form control holds: a string from
935
+ * a back end, a Date from older code, or the library's own objects. It was
936
+ * typed `RangeFieldValue | null` and threw on the first of those.
937
+ */
938
+ writeValue(value) {
939
+ if (value === null || value === undefined) {
940
+ this.value.set(EMPTY$3);
941
+ return;
942
+ }
943
+ // Two moments, nothing else. An allDay a form still carries is ignored:
944
+ // whether a period is whole days is read off the moments themselves.
945
+ const pair = pairIn(value);
946
+ this.value.set({ start: pair.start, end: pair.end });
947
+ }
948
+ registerOnChange(fn) {
949
+ this.onChange = (next) => fn(pairOut(next, this.valueAs(), {}));
950
+ }
951
+ registerOnTouched(fn) {
952
+ this.onTouched = fn;
953
+ }
954
+ setDisabledState(isDisabled) {
955
+ this.formDisabled.set(isDisabled);
956
+ }
957
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: RangeField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
958
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: RangeField, isStandalone: true, selector: "tz-range-field", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: false, transformFunction: null }, presets: { classPropertyName: "presets", publicName: "presets", isSignal: true, isRequired: false, transformFunction: null }, openEnded: { classPropertyName: "openEnded", publicName: "openEnded", isSignal: true, isRequired: false, transformFunction: null }, title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: false, transformFunction: null }, timeLayout: { classPropertyName: "timeLayout", publicName: "timeLayout", isSignal: true, isRequired: false, transformFunction: null }, showTime: { classPropertyName: "showTime", publicName: "showTime", isSignal: true, isRequired: false, transformFunction: null }, defaultTimes: { classPropertyName: "defaultTimes", publicName: "defaultTimes", isSignal: true, isRequired: false, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, snapMinutes: { classPropertyName: "snapMinutes", publicName: "snapMinutes", isSignal: true, isRequired: false, transformFunction: null }, maxSpan: { classPropertyName: "maxSpan", publicName: "maxSpan", isSignal: true, isRequired: false, transformFunction: null }, minSpan: { classPropertyName: "minSpan", publicName: "minSpan", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, confirm: { classPropertyName: "confirm", publicName: "confirm", isSignal: true, isRequired: false, transformFunction: null }, shift: { classPropertyName: "shift", publicName: "shift", isSignal: true, isRequired: false, transformFunction: null }, showPresets: { classPropertyName: "showPresets", publicName: "showPresets", isSignal: true, isRequired: false, transformFunction: null }, showStep: { classPropertyName: "showStep", publicName: "showStep", isSignal: true, isRequired: false, transformFunction: null }, singleDay: { classPropertyName: "singleDay", publicName: "singleDay", isSignal: true, isRequired: false, transformFunction: null }, months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, ariaLabel: { classPropertyName: "ariaLabel", publicName: "ariaLabel", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, now: { classPropertyName: "now", publicName: "now", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, fieldIcon: { classPropertyName: "fieldIcon", publicName: "fieldIcon", isSignal: true, isRequired: false, transformFunction: null }, fieldIconSide: { classPropertyName: "fieldIconSide", publicName: "fieldIconSide", isSignal: true, isRequired: false, transformFunction: null }, labels: { classPropertyName: "labels", publicName: "labels", isSignal: true, isRequired: false, transformFunction: null }, mask: { classPropertyName: "mask", publicName: "mask", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", opened: "opened", closed: "closed" }, providers: [
959
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RangeField), multi: true },
960
+ ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
961
+ }
962
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: RangeField, decorators: [{
963
+ type: Component,
964
+ args: [{
965
+ selector: 'tz-range-field',
966
+ standalone: true,
967
+ changeDetection: ChangeDetectionStrategy.OnPush,
968
+ providers: [
969
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RangeField), multi: true },
970
+ ],
971
+ template: '',
972
+ }]
973
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: false }] }], presets: [{ type: i0.Input, args: [{ isSignal: true, alias: "presets", required: false }] }], openEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "openEnded", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], timeLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLayout", required: false }] }], showTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "showTime", required: false }] }], defaultTimes: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTimes", required: false }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], snapMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapMinutes", required: false }] }], maxSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSpan", required: false }] }], minSpan: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSpan", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], confirm: [{ type: i0.Input, args: [{ isSignal: true, alias: "confirm", required: false }] }], shift: [{ type: i0.Input, args: [{ isSignal: true, alias: "shift", required: false }] }], showPresets: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPresets", required: false }] }], showStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "showStep", required: false }] }], singleDay: [{ type: i0.Input, args: [{ isSignal: true, alias: "singleDay", required: false }] }], months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], placeholder: [{ type: i0.Input, args: [{ isSignal: true, alias: "placeholder", required: false }] }], ariaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "ariaLabel", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], now: [{ type: i0.Input, args: [{ isSignal: true, alias: "now", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], fieldIcon: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldIcon", required: false }] }], fieldIconSide: [{ type: i0.Input, args: [{ isSignal: true, alias: "fieldIconSide", required: false }] }], labels: [{ type: i0.Input, args: [{ isSignal: true, alias: "labels", required: false }] }], mask: [{ type: i0.Input, args: [{ isSignal: true, alias: "mask", required: false }] }], displayWith: [{ type: i0.Input, args: [{ isSignal: true, alias: "displayWith", required: false }] }], opened: [{ type: i0.Output, args: ["opened"] }], closed: [{ type: i0.Output, args: ["closed"] }] } });
429
974
 
430
975
  const EMPTY$2 = { start: null, end: null };
431
976
  /** `<tz-date-range>` — the range from @tzslot/dom, spoken in Angular. */
432
977
  class DateRange {
433
978
  constructor() {
979
+ /** Set once for the application with provideTzslot(); a binding still wins. */
980
+ this.defaults = inject(TZSLOT_DEFAULTS);
434
981
  this.value = model(EMPTY$2, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
435
- this.firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
436
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
982
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
983
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
984
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
437
985
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
438
986
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
439
987
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -441,6 +989,10 @@ class DateRange {
441
989
  this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
442
990
  /** Refuse a range that steps over a day isDateDisabled rules out. On by default. */
443
991
  this.blockAcrossDisabled = input(true, ...(ngDevMode ? [{ debugName: "blockAcrossDisabled" }] : /* istanbul ignore next */ []));
992
+ /** A column of ISO week numbers down the left. */
993
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
994
+ /** How many months to show side by side. Two is what most ranges want. */
995
+ this.months = input(1, ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
444
996
  /** Adds to each day: a price per night, places left, a class of your own. */
445
997
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
446
998
  /** Overrides the bundle for this one instance. */
@@ -462,6 +1014,8 @@ class DateRange {
462
1014
  blockAcrossDisabled: this.blockAcrossDisabled(),
463
1015
  rangeSpansBlockedMessage: this.rangeSpansBlockedMessage(),
464
1016
  renderCell: this.renderCell(),
1017
+ weekNumbers: this.weekNumbers(),
1018
+ months: this.months(),
465
1019
  messages: this.messages,
466
1020
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
467
1021
  this.range = createDateRange(this.host, {
@@ -508,7 +1062,7 @@ class DateRange {
508
1062
  this.formDisabled.set(isDisabled);
509
1063
  }
510
1064
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateRange, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
511
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: DateRange, isStandalone: true, selector: "tz-date-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, blockAcrossDisabled: { classPropertyName: "blockAcrossDisabled", publicName: "blockAcrossDisabled", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, rangeSpansBlockedMessage: { classPropertyName: "rangeSpansBlockedMessage", publicName: "rangeSpansBlockedMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
1065
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: DateRange, isStandalone: true, selector: "tz-date-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, blockAcrossDisabled: { classPropertyName: "blockAcrossDisabled", publicName: "blockAcrossDisabled", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, months: { classPropertyName: "months", publicName: "months", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, rangeSpansBlockedMessage: { classPropertyName: "rangeSpansBlockedMessage", publicName: "rangeSpansBlockedMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
512
1066
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateRange), multi: true },
513
1067
  ], viewQueries: [{ propertyName: "prevSlot", first: true, predicate: ["prev"], descendants: true, isSignal: true }, { propertyName: "nextSlot", first: true, predicate: ["next"], descendants: true, isSignal: true }], ngImport: i0, template: `
514
1068
  <span #prev hidden><ng-content select="[tzPrev]" /></span>
@@ -529,7 +1083,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
529
1083
  <span #next hidden><ng-content select="[tzNext]" /></span>
530
1084
  `,
531
1085
  }]
532
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], blockAcrossDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockAcrossDisabled", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], rangeSpansBlockedMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeSpansBlockedMessage", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
1086
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], blockAcrossDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "blockAcrossDisabled", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], months: [{ type: i0.Input, args: [{ isSignal: true, alias: "months", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], rangeSpansBlockedMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "rangeSpansBlockedMessage", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
533
1087
  /** Whatever was projected into a slot, or undefined so the default chevron stays. */
534
1088
  function projected(host, slot) {
535
1089
  const nodes = Array.from(slot.nativeElement.childNodes);
@@ -549,15 +1103,59 @@ const EMPTY$1 = { start: null, end: null };
549
1103
  */
550
1104
  class DateTimeRange {
551
1105
  constructor() {
1106
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1107
+ this.defaults = inject(TZSLOT_DEFAULTS);
552
1108
  this.value = model(EMPTY$1, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
553
- this.timeZone = input.required(...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
1109
+ /**
1110
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
1111
+ * is the zone provideTzslot() settled for the application, and only when
1112
+ * nothing was settled anywhere does it fall back to the browser's — which
1113
+ * is a guess, and the one thing this library exists not to do silently.
1114
+ */
1115
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
1116
+ /**
1117
+ * Whole days rather than moments. Two-way: the switch inside the widget
1118
+ * sets it, and so can you.
1119
+ */
1120
+ /**
1121
+ * What the form control holds. `'utc'` gives two ISO strings; the default
1122
+ * gives the library's own moments.
1123
+ */
1124
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
1125
+ this.allDay = model(false, ...(ngDevMode ? [{ debugName: "allDay" }] : /* istanbul ignore next */ []));
1126
+ /** Whether that switch is shown at all. */
1127
+ this.allDaySwitch = input(true, ...(ngDevMode ? [{ debugName: "allDaySwitch" }] : /* istanbul ignore next */ []));
1128
+ /**
1129
+ * Lets the interval stop at one end. The summary then says what it means —
1130
+ * "From 14 Sept 2026, 09:00" — instead of going blank, which reads as
1131
+ * nothing chosen. Off by default.
1132
+ */
1133
+ this.openEnded = input(false, ...(ngDevMode ? [{ debugName: "openEnded" }] : /* istanbul ignore next */ []));
1134
+ /** How each end asks for its time: 'input', 'select' or 'list'. */
1135
+ this.timeLayout = input('input', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
554
1136
  this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
1137
+ /** With 'select': minutes between the options. Every minute by default. */
1138
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
1139
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
1140
+ /** The time a newly chosen day starts at. Midnight by default. */
1141
+ this.defaultTime = input('00:00', ...(ngDevMode ? [{ debugName: "defaultTime" }] : /* istanbul ignore next */ []));
1142
+ /** Both ends can be typed into as well as chosen from. */
1143
+ this.editable = input(true, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
1144
+ /** A pattern for both ends — `yyyy-MM-dd HH:mm`. */
1145
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
1146
+ this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
1147
+ /** Which day is today, in both panels. */
1148
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
1149
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
1150
+ /** A column of ISO week numbers down the left. */
1151
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
1152
+ this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
555
1153
  this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
556
1154
  this.maxTime = input(undefined, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
557
1155
  this.isSlotDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isSlotDisabled" }] : /* istanbul ignore next */ []));
558
1156
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
559
1157
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
560
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
1158
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
561
1159
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
562
1160
  this.startLabel = input(undefined, ...(ngDevMode ? [{ debugName: "startLabel" }] : /* istanbul ignore next */ []));
563
1161
  this.endLabel = input(undefined, ...(ngDevMode ? [{ debugName: "endLabel" }] : /* istanbul ignore next */ []));
@@ -567,7 +1165,21 @@ class DateTimeRange {
567
1165
  this.settings = computed(() => ({
568
1166
  value: this.value(),
569
1167
  timeZone: this.timeZone(),
1168
+ allDay: this.allDay(),
1169
+ allDaySwitch: this.allDaySwitch(),
1170
+ openEnded: this.openEnded(),
1171
+ timeLayout: this.timeLayout(),
570
1172
  stepMinutes: this.stepMinutes(),
1173
+ minuteStep: this.minuteStep(),
1174
+ hour12: this.hour12(),
1175
+ defaultTime: this.defaultTime(),
1176
+ editable: this.editable(),
1177
+ format: this.format(),
1178
+ isDateDisabled: this.isDateDisabled(),
1179
+ today: this.today(),
1180
+ renderCell: this.renderCell(),
1181
+ buttons: this.buttons(),
1182
+ weekNumbers: this.weekNumbers(),
571
1183
  minTime: this.minTime(),
572
1184
  maxTime: this.maxTime(),
573
1185
  isSlotDisabled: this.isSlotDisabled(),
@@ -584,6 +1196,7 @@ class DateTimeRange {
584
1196
  this.range = createDateTimeRange(inject(ElementRef).nativeElement, {
585
1197
  messages: this.messages,
586
1198
  onChange: (next) => {
1199
+ this.allDay.set(next.allDay === true);
587
1200
  this.value.set(next);
588
1201
  this.onChange(next);
589
1202
  this.onTouched();
@@ -606,11 +1219,21 @@ class DateTimeRange {
606
1219
  clear() {
607
1220
  this.range.clear();
608
1221
  }
1222
+ /**
1223
+ * Typed `unknown` because that is what a form control holds: a string from
1224
+ * a back end, a Date from older code, or the library's own objects.
1225
+ */
609
1226
  writeValue(value) {
610
- this.value.set(value ?? EMPTY$1);
1227
+ if (value === null || value === undefined) {
1228
+ this.value.set({ start: null, end: null });
1229
+ return;
1230
+ }
1231
+ const pair = pairIn(value);
1232
+ const allDay = value.allDay;
1233
+ this.value.set(allDay === undefined ? pair : { ...pair, allDay });
611
1234
  }
612
1235
  registerOnChange(fn) {
613
- this.onChange = fn;
1236
+ this.onChange = (next) => fn(pairOut(next, this.valueAs(), { allDay: next.allDay === true }));
614
1237
  }
615
1238
  registerOnTouched(fn) {
616
1239
  this.onTouched = fn;
@@ -619,7 +1242,7 @@ class DateTimeRange {
619
1242
  this.formDisabled.set(isDisabled);
620
1243
  }
621
1244
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateTimeRange, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
622
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: DateTimeRange, isStandalone: true, selector: "tz-datetime-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: true, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, isSlotDisabled: { classPropertyName: "isSlotDisabled", publicName: "isSlotDisabled", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, endLabel: { classPropertyName: "endLabel", publicName: "endLabel", isSignal: true, isRequired: false, transformFunction: null }, endBeforeStartMessage: { classPropertyName: "endBeforeStartMessage", publicName: "endBeforeStartMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
1245
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: DateTimeRange, isStandalone: true, selector: "tz-datetime-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, allDay: { classPropertyName: "allDay", publicName: "allDay", isSignal: true, isRequired: false, transformFunction: null }, allDaySwitch: { classPropertyName: "allDaySwitch", publicName: "allDaySwitch", isSignal: true, isRequired: false, transformFunction: null }, openEnded: { classPropertyName: "openEnded", publicName: "openEnded", isSignal: true, isRequired: false, transformFunction: null }, timeLayout: { classPropertyName: "timeLayout", publicName: "timeLayout", isSignal: true, isRequired: false, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, hour12: { classPropertyName: "hour12", publicName: "hour12", isSignal: true, isRequired: false, transformFunction: null }, defaultTime: { classPropertyName: "defaultTime", publicName: "defaultTime", isSignal: true, isRequired: false, transformFunction: null }, editable: { classPropertyName: "editable", publicName: "editable", isSignal: true, isRequired: false, transformFunction: null }, format: { classPropertyName: "format", publicName: "format", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, isSlotDisabled: { classPropertyName: "isSlotDisabled", publicName: "isSlotDisabled", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, startLabel: { classPropertyName: "startLabel", publicName: "startLabel", isSignal: true, isRequired: false, transformFunction: null }, endLabel: { classPropertyName: "endLabel", publicName: "endLabel", isSignal: true, isRequired: false, transformFunction: null }, endBeforeStartMessage: { classPropertyName: "endBeforeStartMessage", publicName: "endBeforeStartMessage", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", allDay: "allDayChange" }, providers: [
623
1246
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeRange), multi: true },
624
1247
  ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
625
1248
  }
@@ -634,7 +1257,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
634
1257
  ],
635
1258
  template: '',
636
1259
  }]
637
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: true }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], isSlotDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSlotDisabled", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], endLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endLabel", required: false }] }], endBeforeStartMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "endBeforeStartMessage", required: false }] }] } });
1260
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], allDay: [{ type: i0.Input, args: [{ isSignal: true, alias: "allDay", required: false }] }, { type: i0.Output, args: ["allDayChange"] }], allDaySwitch: [{ type: i0.Input, args: [{ isSignal: true, alias: "allDaySwitch", required: false }] }], openEnded: [{ type: i0.Input, args: [{ isSignal: true, alias: "openEnded", required: false }] }], timeLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLayout", required: false }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], hour12: [{ type: i0.Input, args: [{ isSignal: true, alias: "hour12", required: false }] }], defaultTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultTime", required: false }] }], editable: [{ type: i0.Input, args: [{ isSignal: true, alias: "editable", required: false }] }], format: [{ type: i0.Input, args: [{ isSignal: true, alias: "format", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], isSlotDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isSlotDisabled", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], startLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "startLabel", required: false }] }], endLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "endLabel", required: false }] }], endBeforeStartMessage: [{ type: i0.Input, args: [{ isSignal: true, alias: "endBeforeStartMessage", required: false }] }] } });
638
1261
 
639
1262
  const EMPTY = { start: null, end: null, from: null, to: null };
640
1263
  /**
@@ -643,15 +1266,29 @@ const EMPTY = { start: null, end: null, from: null, to: null };
643
1266
  */
644
1267
  class DailyRange {
645
1268
  constructor() {
1269
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1270
+ this.defaults = inject(TZSLOT_DEFAULTS);
646
1271
  this.value = model(EMPTY, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
647
- /** An IANA identifier. The hours are read on the clocks of this zone. */
648
- this.timeZone = input.required(...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
1272
+ /**
1273
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
1274
+ * is the zone provideTzslot() settled for the application, and only when
1275
+ * nothing was settled anywhere does it fall back to the browser's — which
1276
+ * is a guess, and the one thing this library exists not to do silently.
1277
+ */
1278
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
649
1279
  this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
1280
+ /** 'input' (default) for two compact fields, 'list' for times to click. */
1281
+ this.timeLayout = input('input', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
1282
+ /** 12-hour fields with an AM/PM button; the locale decides when unset. */
1283
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
1284
+ /** With timeLayout 'columns': minutes between the options. Every minute by default. */
1285
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
650
1286
  /** The first and last times offered. */
651
1287
  this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
652
1288
  this.maxTime = input(undefined, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
653
- this.firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
654
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
1289
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
1290
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
1291
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
655
1292
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
656
1293
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
657
1294
  this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
@@ -666,6 +1303,9 @@ class DailyRange {
666
1303
  value: this.value(),
667
1304
  timeZone: this.timeZone(),
668
1305
  stepMinutes: this.stepMinutes(),
1306
+ timeLayout: this.timeLayout(),
1307
+ hour12: this.hour12(),
1308
+ minuteStep: this.minuteStep(),
669
1309
  minTime: this.minTime(),
670
1310
  maxTime: this.maxTime(),
671
1311
  firstDayOfWeek: this.firstDayOfWeek(),
@@ -707,6 +1347,11 @@ class DailyRange {
707
1347
  clear() {
708
1348
  this.range.clear();
709
1349
  }
1350
+ /**
1351
+ * A pattern, not a moment: two days and the clock faces repeated over them.
1352
+ * `valueAs` has nothing to convert here, which is why this component does
1353
+ * not take it — see the note on TzslotDefaults.
1354
+ */
710
1355
  writeValue(value) {
711
1356
  this.value.set(value ?? EMPTY);
712
1357
  }
@@ -720,7 +1365,7 @@ class DailyRange {
720
1365
  this.formDisabled.set(isDisabled);
721
1366
  }
722
1367
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DailyRange, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
723
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: DailyRange, isStandalone: true, selector: "tz-daily-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: true, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
1368
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "21.2.23", type: DailyRange, isStandalone: true, selector: "tz-daily-range", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, timeZone: { classPropertyName: "timeZone", publicName: "timeZone", isSignal: true, isRequired: false, transformFunction: null }, stepMinutes: { classPropertyName: "stepMinutes", publicName: "stepMinutes", isSignal: true, isRequired: false, transformFunction: null }, timeLayout: { classPropertyName: "timeLayout", publicName: "timeLayout", isSignal: true, isRequired: false, transformFunction: null }, hour12: { classPropertyName: "hour12", publicName: "hour12", isSignal: true, isRequired: false, transformFunction: null }, minuteStep: { classPropertyName: "minuteStep", publicName: "minuteStep", isSignal: true, isRequired: false, transformFunction: null }, minTime: { classPropertyName: "minTime", publicName: "minTime", isSignal: true, isRequired: false, transformFunction: null }, maxTime: { classPropertyName: "maxTime", publicName: "maxTime", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, providers: [
724
1369
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DailyRange), multi: true },
725
1370
  ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
726
1371
  }
@@ -735,7 +1380,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
735
1380
  ],
736
1381
  template: '',
737
1382
  }]
738
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: true }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
1383
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], timeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeZone", required: false }] }], stepMinutes: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepMinutes", required: false }] }], timeLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "timeLayout", required: false }] }], hour12: [{ type: i0.Input, args: [{ isSignal: true, alias: "hour12", required: false }] }], minuteStep: [{ type: i0.Input, args: [{ isSignal: true, alias: "minuteStep", required: false }] }], minTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "minTime", required: false }] }], maxTime: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxTime", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }] } });
739
1384
 
740
1385
  /**
741
1386
  * `<tz-multi-date>` — several days, not necessarily next to each other, from
@@ -743,12 +1388,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
743
1388
  */
744
1389
  class MultiDate {
745
1390
  constructor() {
1391
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1392
+ this.defaults = inject(TZSLOT_DEFAULTS);
746
1393
  /** The chosen days, in date order. Two-way: `[(value)]`. */
747
1394
  this.value = model([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
748
1395
  /** Once this many are chosen, the other days stop taking clicks. */
749
1396
  this.maxDates = input(undefined, ...(ngDevMode ? [{ debugName: "maxDates" }] : /* istanbul ignore next */ []));
750
- this.firstDayOfWeek = input(1, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
751
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
1397
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
1398
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
1399
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
752
1400
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
753
1401
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
754
1402
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -756,11 +1404,13 @@ class MultiDate {
756
1404
  this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
757
1405
  this.view = model('days', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
758
1406
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
1407
+ /** A column of ISO week numbers down the left. */
1408
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
759
1409
  this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
760
1410
  /** What the form control holds, each day as a Temporal date, a Date, or an ISO string. */
761
- this.valueAs = input('temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
1411
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
762
1412
  /** The zone a Date is read in. Only consulted when valueAs is 'date'. */
763
- this.valueTimeZone = input(Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
1413
+ this.valueTimeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
764
1414
  this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
765
1415
  this.host = inject(ElementRef).nativeElement;
766
1416
  this.messages = inject(TZSLOT_MESSAGES);
@@ -779,6 +1429,7 @@ class MultiDate {
779
1429
  today: this.today(),
780
1430
  renderCell: this.renderCell(),
781
1431
  buttons: this.buttons(),
1432
+ weekNumbers: this.weekNumbers(),
782
1433
  messages: this.messages,
783
1434
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
784
1435
  this.calendar = createMultiDate(this.host, {
@@ -836,7 +1487,7 @@ class MultiDate {
836
1487
  this.formDisabled.set(isDisabled);
837
1488
  }
838
1489
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: MultiDate, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
839
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: MultiDate, isStandalone: true, selector: "tz-multi-date", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, maxDates: { classPropertyName: "maxDates", publicName: "maxDates", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", view: "viewChange" }, providers: [
1490
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "21.2.23", type: MultiDate, isStandalone: true, selector: "tz-multi-date", inputs: { value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, maxDates: { classPropertyName: "maxDates", publicName: "maxDates", isSignal: true, isRequired: false, transformFunction: null }, firstDayOfWeek: { classPropertyName: "firstDayOfWeek", publicName: "firstDayOfWeek", isSignal: true, isRequired: false, transformFunction: null }, locale: { classPropertyName: "locale", publicName: "locale", isSignal: true, isRequired: false, transformFunction: null }, min: { classPropertyName: "min", publicName: "min", isSignal: true, isRequired: false, transformFunction: null }, max: { classPropertyName: "max", publicName: "max", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, isDateDisabled: { classPropertyName: "isDateDisabled", publicName: "isDateDisabled", isSignal: true, isRequired: false, transformFunction: null }, today: { classPropertyName: "today", publicName: "today", isSignal: true, isRequired: false, transformFunction: null }, view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: false, transformFunction: null }, renderCell: { classPropertyName: "renderCell", publicName: "renderCell", isSignal: true, isRequired: false, transformFunction: null }, weekNumbers: { classPropertyName: "weekNumbers", publicName: "weekNumbers", isSignal: true, isRequired: false, transformFunction: null }, buttons: { classPropertyName: "buttons", publicName: "buttons", isSignal: true, isRequired: false, transformFunction: null }, valueAs: { classPropertyName: "valueAs", publicName: "valueAs", isSignal: true, isRequired: false, transformFunction: null }, valueTimeZone: { classPropertyName: "valueTimeZone", publicName: "valueTimeZone", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", view: "viewChange" }, providers: [
840
1491
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MultiDate), multi: true },
841
1492
  ], viewQueries: [{ propertyName: "prevSlot", first: true, predicate: ["prev"], descendants: true, isSignal: true }, { propertyName: "nextSlot", first: true, predicate: ["next"], descendants: true, isSignal: true }], ngImport: i0, template: `
842
1493
  <span #prev hidden><ng-content select="[tzPrev]" /></span>
@@ -857,7 +1508,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
857
1508
  <span #next hidden><ng-content select="[tzNext]" /></span>
858
1509
  `,
859
1510
  }]
860
- }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], maxDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDates", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
1511
+ }], ctorParameters: () => [], propDecorators: { value: [{ type: i0.Input, args: [{ isSignal: true, alias: "value", required: false }] }, { type: i0.Output, args: ["valueChange"] }], maxDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxDates", required: false }] }], firstDayOfWeek: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstDayOfWeek", required: false }] }], locale: [{ type: i0.Input, args: [{ isSignal: true, alias: "locale", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], isDateDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "isDateDisabled", required: false }] }], today: [{ type: i0.Input, args: [{ isSignal: true, alias: "today", required: false }] }], view: [{ type: i0.Input, args: [{ isSignal: true, alias: "view", required: false }] }, { type: i0.Output, args: ["viewChange"] }], renderCell: [{ type: i0.Input, args: [{ isSignal: true, alias: "renderCell", required: false }] }], weekNumbers: [{ type: i0.Input, args: [{ isSignal: true, alias: "weekNumbers", required: false }] }], buttons: [{ type: i0.Input, args: [{ isSignal: true, alias: "buttons", required: false }] }], valueAs: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueAs", required: false }] }], valueTimeZone: [{ type: i0.Input, args: [{ isSignal: true, alias: "valueTimeZone", required: false }] }], prevSlot: [{ type: i0.ViewChild, args: ['prev', { isSignal: true }] }], nextSlot: [{ type: i0.ViewChild, args: ['next', { isSignal: true }] }] } });
861
1512
 
862
1513
  /**
863
1514
  * @tzslot/ui — Angular components over the core.
@@ -871,5 +1522,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
871
1522
  * Generated bundle index. Do not edit.
872
1523
  */
873
1524
 
874
- export { Calendar, DailyRange, DateField, DateRange, DateTimeRange, MultiDate, TZSLOT_MESSAGES, TimeSlotPicker, provideTzslotMessages };
1525
+ export { Calendar, DailyRange, DateField, DateRange, DateTimeField, DateTimeRange, MultiDate, RangeField, TZSLOT_DEFAULTS, TZSLOT_MESSAGES, TimeSlotPicker, pairIn, pairOut, provideTzslot, provideTzslotMessages };
875
1526
  //# sourceMappingURL=tzslot-angular.mjs.map