@tzslot/angular 0.1.0-beta.0 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,479 @@ 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
+ this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
548
+ /** With timeLayout 'select': minutes between the options. Every minute by default. */
549
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
550
+ this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
551
+ this.maxTime = input(undefined, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
552
+ /** Only with timeLayout 'list': rules out slots while still showing them. */
553
+ this.isSlotDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isSlotDisabled" }] : /* istanbul ignore next */ []));
554
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
555
+ /** The time a newly chosen day starts at. Midnight by default. */
556
+ this.defaultTime = input('00:00', ...(ngDevMode ? [{ debugName: "defaultTime" }] : /* istanbul ignore next */ []));
557
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
558
+ /** The text can be typed as well as chosen. On by default. */
559
+ this.editable = input(true, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
560
+ /** Separators appear as the figures are typed, like a card number. On by default. */
561
+ this.mask = input(true, ...(ngDevMode ? [{ debugName: "mask" }] : /* istanbul ignore next */ []));
562
+ /** A pattern — `yyyy-MM-dd HH:mm` — when the shape matters more than the reader. */
563
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
564
+ /** Used when the field is not typable and no pattern is given. */
565
+ this.dateStyle = input('medium', ...(ngDevMode ? [{ debugName: "dateStyle" }] : /* istanbul ignore next */ []));
566
+ this.timeStyle = input('short', ...(ngDevMode ? [{ debugName: "timeStyle" }] : /* istanbul ignore next */ []));
567
+ /** The last word on the text. Given both, this one wins. */
568
+ this.displayWith = input(undefined, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
569
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
570
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
571
+ /** A column of ISO week numbers down the left. */
572
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
573
+ this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
574
+ /** What the form control holds: a Temporal Instant, a Date, or an ISO string. */
575
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
576
+ this.opened = output();
577
+ this.closed = output();
578
+ /** Whether the panel is showing. Readable from a ViewChild. */
579
+ this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
580
+ this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
581
+ /** Set while the component is being destroyed, so no output fires after it. */
582
+ this.gone = false;
583
+ this.host = inject(ElementRef).nativeElement;
584
+ this.messages = inject(TZSLOT_MESSAGES);
585
+ this.iconSlot = viewChild.required('icon');
586
+ this.settings = computed(() => ({
587
+ value: this.value(),
588
+ timeZone: this.timeZone(),
589
+ mode: this.mode(),
590
+ placeholder: this.placeholder(),
591
+ ariaLabel: this.ariaLabel(),
592
+ locale: this.locale(),
593
+ firstDayOfWeek: this.firstDayOfWeek(),
594
+ min: this.min(),
595
+ max: this.max(),
596
+ isDateDisabled: this.isDateDisabled(),
597
+ showTime: this.showTime(),
598
+ timeLayout: this.timeLayout(),
599
+ snapMinutes: this.snapMinutes(),
600
+ shift: this.shift(),
601
+ stepMinutes: this.stepMinutes(),
602
+ minuteStep: this.minuteStep(),
603
+ minTime: this.minTime(),
604
+ maxTime: this.maxTime(),
605
+ isSlotDisabled: this.isSlotDisabled(),
606
+ hour12: this.hour12(),
607
+ defaultTime: this.defaultTime(),
608
+ disabled: this.disabled() || this.formDisabled(),
609
+ editable: this.editable(),
610
+ mask: this.mask(),
611
+ format: this.format(),
612
+ dateStyle: this.dateStyle(),
613
+ timeStyle: this.timeStyle(),
614
+ displayWith: this.displayWith(),
615
+ today: this.today(),
616
+ renderCell: this.renderCell(),
617
+ buttons: this.buttons(),
618
+ weekNumbers: this.weekNumbers(),
619
+ messages: this.messages,
620
+ }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
621
+ /** Created before the required timeZone is bound; the first change detection fills it in. */
622
+ this.field = createDateTimeField(this.host, {
623
+ messages: this.messages,
624
+ onChange: (value) => {
625
+ this.value.set(value);
626
+ this.onChange(value);
627
+ },
628
+ onOpen: () => {
629
+ this.isOpen.set(true);
630
+ this.onTouched();
631
+ if (!this.gone)
632
+ this.opened.emit();
633
+ },
634
+ onClose: () => {
635
+ this.isOpen.set(false);
636
+ // Destroying the component closes its panel; an output that fires then
637
+ // is an emit on a destroyed ref (NG0953), and nothing is listening.
638
+ if (!this.gone)
639
+ this.closed.emit();
640
+ },
641
+ });
642
+ // ── ControlValueAccessor ────────────────────────────────────
643
+ this.onChange = () => { };
644
+ this.onTouched = () => { };
645
+ effect(() => {
646
+ const settings = this.settings();
647
+ untracked(() => this.field.update(settings));
648
+ });
649
+ inject(DestroyRef).onDestroy(() => {
650
+ this.gone = true;
651
+ this.field.destroy();
652
+ });
653
+ }
654
+ ngAfterViewInit() {
655
+ const slot = this.iconSlot().nativeElement;
656
+ if (Array.from(slot.childNodes).some((n) => n.nodeType === Node.ELEMENT_NODE || n.textContent?.trim())) {
657
+ const fragment = this.host.ownerDocument.createDocumentFragment();
658
+ fragment.append(...Array.from(slot.childNodes));
659
+ this.field.setIcon(fragment);
660
+ }
661
+ }
662
+ toggle() {
663
+ this.field.toggle();
664
+ }
665
+ /** No-op when already open. */
666
+ open() {
667
+ this.field.open();
668
+ }
669
+ close() {
670
+ this.field.close();
671
+ }
672
+ /** Clears the selection and tells any form control about it. */
673
+ clear() {
674
+ this.field.clear();
675
+ }
676
+ writeValue(value) {
677
+ this.value.set(value === null || value === undefined ? null : toInstant(value));
678
+ }
679
+ registerOnChange(fn) {
680
+ this.onChange = (value) => fn(fromInstant(value, this.valueAs()));
681
+ }
682
+ registerOnTouched(fn) {
683
+ this.onTouched = fn;
684
+ }
685
+ setDisabledState(isDisabled) {
686
+ this.formDisabled.set(isDisabled);
687
+ }
688
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateTimeField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
689
+ 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 }, 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: [
690
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeField), multi: true },
691
+ ], 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 }); }
692
+ }
693
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: DateTimeField, decorators: [{
694
+ type: Component,
695
+ args: [{
696
+ selector: 'tz-datetime-field',
697
+ standalone: true,
698
+ changeDetection: ChangeDetectionStrategy.OnPush,
699
+ providers: [
700
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeField), multi: true },
701
+ ],
702
+ template: `<span #icon hidden><ng-content select="[tzIcon]" /></span>`,
703
+ }]
704
+ }], 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 }] }], 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 }] }] } });
705
+
706
+ const EMPTY$3 = { start: null, end: null };
707
+ /**
708
+ * `<tz-range-field>` — one field for a period, from @tzslot/dom, spoken in
709
+ * Angular. Named ranges beside the calendar, months side by side, and whole
710
+ * days or moments.
711
+ */
712
+ class RangeField {
713
+ constructor() {
714
+ /** Set once for the application with provideTzslot(); a binding still wins. */
715
+ this.defaults = inject(TZSLOT_DEFAULTS);
716
+ this.value = model(EMPTY$3, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
717
+ /**
718
+ * What the form control holds. `'utc'` gives two ISO strings; the default
719
+ * gives the library's own moments. Settled for a whole application with
720
+ * provideTzslot(), which documents it as applying to every component — and
721
+ * this one did not listen.
722
+ */
723
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
724
+ /**
725
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
726
+ * is the zone provideTzslot() settled for the application, and only when
727
+ * nothing was settled anywhere does it fall back to the browser's — which
728
+ * is a guess, and the one thing this library exists not to do silently.
729
+ */
730
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
731
+ /** Named ranges beside the calendar: the built-in names, or your own. */
732
+ this.presets = input([
733
+ 'thisQuarterHour',
734
+ 'lastHour',
735
+ 'thisHour',
736
+ 'nextHour',
737
+ 'yesterday',
738
+ 'today',
739
+ 'tomorrow',
740
+ 'last7Days',
741
+ 'thisMonth',
742
+ 'thisQuarter',
743
+ ], ...(ngDevMode ? [{ debugName: "presets" }] : /* istanbul ignore next */ []));
744
+ /**
745
+ * Lets a period stop at one end — "from 14 September", "until the 20th".
746
+ * The panel then offers Between / From / Until, and each chosen end can be
747
+ * dropped with the cross beside it. Off by default: a booking form must not
748
+ * accept a period with no end.
749
+ */
750
+ this.openEnded = input(false, ...(ngDevMode ? [{ debugName: "openEnded" }] : /* istanbul ignore next */ []));
751
+ /** A word or two saying what is being chosen — "Travel dates". */
752
+ this.title = input(undefined, ...(ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []));
753
+ /** How an hour is asked for: two menus (default), or figures with arrows. */
754
+ this.timeLayout = input('select', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
755
+ /**
756
+ * Whether the period carries times as well as days — the screen's decision,
757
+ * not the reader's. There is no "all day" switch: on, every chosen day
758
+ * starts at `defaultTimes`.
759
+ */
760
+ this.showTime = input(false, ...(ngDevMode ? [{ debugName: "showTime" }] : /* istanbul ignore next */ []));
761
+ /**
762
+ * The hours a newly chosen day is given: midnight unless the screen knows
763
+ * better — `{ start: '09:00', end: '18:00' }` for a working day. A value
764
+ * handed to the field keeps its own hours.
765
+ */
766
+ this.defaultTimes = input({}, ...(ngDevMode ? [{ debugName: "defaultTimes" }] : /* istanbul ignore next */ []));
767
+ this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
768
+ /**
769
+ * Move a time typed by hand to the nearest mark of this grid — 15 for
770
+ * quarter-hour appointments, ties upward. Off by default.
771
+ */
772
+ this.snapMinutes = input(null, ...(ngDevMode ? [{ debugName: "snapMinutes" }] : /* istanbul ignore next */ []));
773
+ /**
774
+ * How long the period may be, and how short — `'30d'`, `{ hours: 2 }`.
775
+ * Moving one end pushes the other rather than refusing the move.
776
+ */
777
+ this.maxSpan = input(null, ...(ngDevMode ? [{ debugName: "maxSpan" }] : /* istanbul ignore next */ []));
778
+ this.minSpan = input(null, ...(ngDevMode ? [{ debugName: "minSpan" }] : /* istanbul ignore next */ []));
779
+ /** Minutes between the options of the hour menu. Five by default. */
780
+ this.minuteStep = input(5, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
781
+ /** Nothing is reported until Apply is pressed. */
782
+ this.confirm = input(false, ...(ngDevMode ? [{ debugName: "confirm" }] : /* istanbul ignore next */ []));
783
+ /**
784
+ * Arrows that step the whole period without opening the panel. `false` —
785
+ * the default — draws none. `'auto'` moves by what is selected; a duration
786
+ * such as `{ months: 3 }` imposes the step.
787
+ */
788
+ this.shift = input(false, ...(ngDevMode ? [{ debugName: "shift" }] : /* istanbul ignore next */ []));
789
+ this.months = input(2, ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
790
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
791
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
792
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
793
+ this.mode = input('popup', ...(ngDevMode ? [{ debugName: "mode" }] : /* istanbul ignore next */ []));
794
+ this.placeholder = input(undefined, ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
795
+ this.ariaLabel = input(undefined, ...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
796
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
797
+ this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
798
+ this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
799
+ this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
800
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
801
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
802
+ /** The moment the shortcuts shorter than a day are counted from. The clock by default. */
803
+ this.now = input(null, ...(ngDevMode ? [{ debugName: "now" }] : /* istanbul ignore next */ []));
804
+ /**
805
+ * The whole field, or one end of it: `{ end: true }` for a period whose end
806
+ * the screen works out itself. A locked end is read-only rather than
807
+ * disabled — still readable, still reachable by the keyboard.
808
+ */
809
+ this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
810
+ /** A pattern for each end — `yyyy-MM-dd`. */
811
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
812
+ /**
813
+ * What is written above the panel's two fields, and between them. Words by
814
+ * default; `{ start: null, end: null, between: '»' }` for a screen that
815
+ * prefers a mark. A DOM node is taken as it is.
816
+ */
817
+ /**
818
+ * The mark inside the panel's two fields — a calendar by default, `null`
819
+ * for none, or a node of your own.
820
+ */
821
+ this.fieldIcon = input(undefined, ...(ngDevMode ? [{ debugName: "fieldIcon" }] : /* istanbul ignore next */ []));
822
+ this.fieldIconSide = input('start', ...(ngDevMode ? [{ debugName: "fieldIconSide" }] : /* istanbul ignore next */ []));
823
+ this.labels = input({}, ...(ngDevMode ? [{ debugName: "labels" }] : /* istanbul ignore next */ []));
824
+ /** Separators appear as figures are typed in those fields. */
825
+ this.mask = input(true, ...(ngDevMode ? [{ debugName: "mask" }] : /* istanbul ignore next */ []));
826
+ this.displayWith = input(undefined, ...(ngDevMode ? [{ debugName: "displayWith" }] : /* istanbul ignore next */ []));
827
+ this.opened = output();
828
+ this.closed = output();
829
+ /** Whether the panel is showing. Readable from a ViewChild. */
830
+ this.isOpen = signal(false, ...(ngDevMode ? [{ debugName: "isOpen" }] : /* istanbul ignore next */ []));
831
+ this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
832
+ this.gone = false;
833
+ this.messages = inject(TZSLOT_MESSAGES);
834
+ this.settings = computed(() => ({
835
+ value: this.value(),
836
+ timeZone: this.timeZone(),
837
+ presets: this.presets(),
838
+ openEnded: this.openEnded(),
839
+ title: this.title(),
840
+ timeLayout: this.timeLayout(),
841
+ showTime: this.showTime(),
842
+ defaultTimes: this.defaultTimes(),
843
+ stepMinutes: this.stepMinutes(),
844
+ snapMinutes: this.snapMinutes(),
845
+ maxSpan: this.maxSpan(),
846
+ minSpan: this.minSpan(),
847
+ minuteStep: this.minuteStep(),
848
+ confirm: this.confirm(),
849
+ shift: this.shift(),
850
+ months: this.months(),
851
+ weekNumbers: this.weekNumbers(),
852
+ firstDayOfWeek: this.firstDayOfWeek(),
853
+ mode: this.mode(),
854
+ placeholder: this.placeholder(),
855
+ ariaLabel: this.ariaLabel(),
856
+ locale: this.locale(),
857
+ min: this.min(),
858
+ max: this.max(),
859
+ isDateDisabled: this.isDateDisabled(),
860
+ renderCell: this.renderCell(),
861
+ today: this.today(),
862
+ now: this.now(),
863
+ // A form disabling the control wins over a per-end lock: it means the
864
+ // whole thing is out of play, not that one end of it is.
865
+ disabled: this.formDisabled() ? true : this.disabled(),
866
+ format: this.format(),
867
+ labels: this.labels(),
868
+ fieldIcon: this.fieldIcon(),
869
+ fieldIconSide: this.fieldIconSide(),
870
+ mask: this.mask(),
871
+ displayWith: this.displayWith(),
872
+ messages: this.messages,
873
+ }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
874
+ /** Created before the required timeZone is bound; the first change detection fills it in. */
875
+ this.field = createRangeField(inject(ElementRef).nativeElement, {
876
+ messages: this.messages,
877
+ onChange: (value) => {
878
+ this.value.set(value);
879
+ this.onChange(value);
880
+ this.onTouched();
881
+ },
882
+ onOpen: () => {
883
+ this.isOpen.set(true);
884
+ if (!this.gone)
885
+ this.opened.emit();
886
+ },
887
+ onClose: () => {
888
+ this.isOpen.set(false);
889
+ if (!this.gone)
890
+ this.closed.emit();
891
+ },
892
+ });
893
+ // ── ControlValueAccessor ────────────────────────────────────
894
+ this.onChange = () => { };
895
+ this.onTouched = () => { };
896
+ effect(() => {
897
+ const settings = this.settings();
898
+ untracked(() => this.field.update(settings));
899
+ });
900
+ inject(DestroyRef).onDestroy(() => {
901
+ this.gone = true;
902
+ this.field.destroy();
903
+ });
904
+ }
905
+ open() {
906
+ this.field.open();
907
+ }
908
+ close() {
909
+ this.field.close();
910
+ }
911
+ toggle() {
912
+ this.field.toggle();
913
+ }
914
+ /** Empties the period and tells any form control about it. */
915
+ clear() {
916
+ this.field.clear();
917
+ }
918
+ /**
919
+ * Typed `unknown` because that is what a form control holds: a string from
920
+ * a back end, a Date from older code, or the library's own objects. It was
921
+ * typed `RangeFieldValue | null` and threw on the first of those.
922
+ */
923
+ writeValue(value) {
924
+ if (value === null || value === undefined) {
925
+ this.value.set(EMPTY$3);
926
+ return;
927
+ }
928
+ // Two moments, nothing else. An allDay a form still carries is ignored:
929
+ // whether a period is whole days is read off the moments themselves.
930
+ const pair = pairIn(value);
931
+ this.value.set({ start: pair.start, end: pair.end });
932
+ }
933
+ registerOnChange(fn) {
934
+ this.onChange = (next) => fn(pairOut(next, this.valueAs(), {}));
935
+ }
936
+ registerOnTouched(fn) {
937
+ this.onTouched = fn;
938
+ }
939
+ setDisabledState(isDisabled) {
940
+ this.formDisabled.set(isDisabled);
941
+ }
942
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: RangeField, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
943
+ 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 }, 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: [
944
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RangeField), multi: true },
945
+ ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
946
+ }
947
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImport: i0, type: RangeField, decorators: [{
948
+ type: Component,
949
+ args: [{
950
+ selector: 'tz-range-field',
951
+ standalone: true,
952
+ changeDetection: ChangeDetectionStrategy.OnPush,
953
+ providers: [
954
+ { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => RangeField), multi: true },
955
+ ],
956
+ template: '',
957
+ }]
958
+ }], 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 }] }], 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
959
 
430
960
  const EMPTY$2 = { start: null, end: null };
431
961
  /** `<tz-date-range>` — the range from @tzslot/dom, spoken in Angular. */
432
962
  class DateRange {
433
963
  constructor() {
964
+ /** Set once for the application with provideTzslot(); a binding still wins. */
965
+ this.defaults = inject(TZSLOT_DEFAULTS);
434
966
  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 */ []));
967
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
968
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
969
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
437
970
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
438
971
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
439
972
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -441,6 +974,10 @@ class DateRange {
441
974
  this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
442
975
  /** Refuse a range that steps over a day isDateDisabled rules out. On by default. */
443
976
  this.blockAcrossDisabled = input(true, ...(ngDevMode ? [{ debugName: "blockAcrossDisabled" }] : /* istanbul ignore next */ []));
977
+ /** A column of ISO week numbers down the left. */
978
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
979
+ /** How many months to show side by side. Two is what most ranges want. */
980
+ this.months = input(1, ...(ngDevMode ? [{ debugName: "months" }] : /* istanbul ignore next */ []));
444
981
  /** Adds to each day: a price per night, places left, a class of your own. */
445
982
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
446
983
  /** Overrides the bundle for this one instance. */
@@ -462,6 +999,8 @@ class DateRange {
462
999
  blockAcrossDisabled: this.blockAcrossDisabled(),
463
1000
  rangeSpansBlockedMessage: this.rangeSpansBlockedMessage(),
464
1001
  renderCell: this.renderCell(),
1002
+ weekNumbers: this.weekNumbers(),
1003
+ months: this.months(),
465
1004
  messages: this.messages,
466
1005
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
467
1006
  this.range = createDateRange(this.host, {
@@ -508,7 +1047,7 @@ class DateRange {
508
1047
  this.formDisabled.set(isDisabled);
509
1048
  }
510
1049
  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: [
1050
+ 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
1051
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateRange), multi: true },
513
1052
  ], 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
1053
  <span #prev hidden><ng-content select="[tzPrev]" /></span>
@@ -529,7 +1068,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
529
1068
  <span #next hidden><ng-content select="[tzNext]" /></span>
530
1069
  `,
531
1070
  }]
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 }] }] } });
1071
+ }], 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
1072
  /** Whatever was projected into a slot, or undefined so the default chevron stays. */
534
1073
  function projected(host, slot) {
535
1074
  const nodes = Array.from(slot.nativeElement.childNodes);
@@ -549,15 +1088,59 @@ const EMPTY$1 = { start: null, end: null };
549
1088
  */
550
1089
  class DateTimeRange {
551
1090
  constructor() {
1091
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1092
+ this.defaults = inject(TZSLOT_DEFAULTS);
552
1093
  this.value = model(EMPTY$1, ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
553
- this.timeZone = input.required(...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
1094
+ /**
1095
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
1096
+ * is the zone provideTzslot() settled for the application, and only when
1097
+ * nothing was settled anywhere does it fall back to the browser's — which
1098
+ * is a guess, and the one thing this library exists not to do silently.
1099
+ */
1100
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
1101
+ /**
1102
+ * Whole days rather than moments. Two-way: the switch inside the widget
1103
+ * sets it, and so can you.
1104
+ */
1105
+ /**
1106
+ * What the form control holds. `'utc'` gives two ISO strings; the default
1107
+ * gives the library's own moments.
1108
+ */
1109
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
1110
+ this.allDay = model(false, ...(ngDevMode ? [{ debugName: "allDay" }] : /* istanbul ignore next */ []));
1111
+ /** Whether that switch is shown at all. */
1112
+ this.allDaySwitch = input(true, ...(ngDevMode ? [{ debugName: "allDaySwitch" }] : /* istanbul ignore next */ []));
1113
+ /**
1114
+ * Lets the interval stop at one end. The summary then says what it means —
1115
+ * "From 14 Sept 2026, 09:00" — instead of going blank, which reads as
1116
+ * nothing chosen. Off by default.
1117
+ */
1118
+ this.openEnded = input(false, ...(ngDevMode ? [{ debugName: "openEnded" }] : /* istanbul ignore next */ []));
1119
+ /** How each end asks for its time: 'input', 'select' or 'list'. */
1120
+ this.timeLayout = input('input', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
554
1121
  this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
1122
+ /** With 'select': minutes between the options. Every minute by default. */
1123
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
1124
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
1125
+ /** The time a newly chosen day starts at. Midnight by default. */
1126
+ this.defaultTime = input('00:00', ...(ngDevMode ? [{ debugName: "defaultTime" }] : /* istanbul ignore next */ []));
1127
+ /** Both ends can be typed into as well as chosen from. */
1128
+ this.editable = input(true, ...(ngDevMode ? [{ debugName: "editable" }] : /* istanbul ignore next */ []));
1129
+ /** A pattern for both ends — `yyyy-MM-dd HH:mm`. */
1130
+ this.format = input(undefined, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
1131
+ this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
1132
+ /** Which day is today, in both panels. */
1133
+ this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
1134
+ this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
1135
+ /** A column of ISO week numbers down the left. */
1136
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
1137
+ this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
555
1138
  this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
556
1139
  this.maxTime = input(undefined, ...(ngDevMode ? [{ debugName: "maxTime" }] : /* istanbul ignore next */ []));
557
1140
  this.isSlotDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isSlotDisabled" }] : /* istanbul ignore next */ []));
558
1141
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
559
1142
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
560
- this.locale = input(undefined, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
1143
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
561
1144
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
562
1145
  this.startLabel = input(undefined, ...(ngDevMode ? [{ debugName: "startLabel" }] : /* istanbul ignore next */ []));
563
1146
  this.endLabel = input(undefined, ...(ngDevMode ? [{ debugName: "endLabel" }] : /* istanbul ignore next */ []));
@@ -567,7 +1150,21 @@ class DateTimeRange {
567
1150
  this.settings = computed(() => ({
568
1151
  value: this.value(),
569
1152
  timeZone: this.timeZone(),
1153
+ allDay: this.allDay(),
1154
+ allDaySwitch: this.allDaySwitch(),
1155
+ openEnded: this.openEnded(),
1156
+ timeLayout: this.timeLayout(),
570
1157
  stepMinutes: this.stepMinutes(),
1158
+ minuteStep: this.minuteStep(),
1159
+ hour12: this.hour12(),
1160
+ defaultTime: this.defaultTime(),
1161
+ editable: this.editable(),
1162
+ format: this.format(),
1163
+ isDateDisabled: this.isDateDisabled(),
1164
+ today: this.today(),
1165
+ renderCell: this.renderCell(),
1166
+ buttons: this.buttons(),
1167
+ weekNumbers: this.weekNumbers(),
571
1168
  minTime: this.minTime(),
572
1169
  maxTime: this.maxTime(),
573
1170
  isSlotDisabled: this.isSlotDisabled(),
@@ -584,6 +1181,7 @@ class DateTimeRange {
584
1181
  this.range = createDateTimeRange(inject(ElementRef).nativeElement, {
585
1182
  messages: this.messages,
586
1183
  onChange: (next) => {
1184
+ this.allDay.set(next.allDay === true);
587
1185
  this.value.set(next);
588
1186
  this.onChange(next);
589
1187
  this.onTouched();
@@ -606,11 +1204,21 @@ class DateTimeRange {
606
1204
  clear() {
607
1205
  this.range.clear();
608
1206
  }
1207
+ /**
1208
+ * Typed `unknown` because that is what a form control holds: a string from
1209
+ * a back end, a Date from older code, or the library's own objects.
1210
+ */
609
1211
  writeValue(value) {
610
- this.value.set(value ?? EMPTY$1);
1212
+ if (value === null || value === undefined) {
1213
+ this.value.set({ start: null, end: null });
1214
+ return;
1215
+ }
1216
+ const pair = pairIn(value);
1217
+ const allDay = value.allDay;
1218
+ this.value.set(allDay === undefined ? pair : { ...pair, allDay });
611
1219
  }
612
1220
  registerOnChange(fn) {
613
- this.onChange = fn;
1221
+ this.onChange = (next) => fn(pairOut(next, this.valueAs(), { allDay: next.allDay === true }));
614
1222
  }
615
1223
  registerOnTouched(fn) {
616
1224
  this.onTouched = fn;
@@ -619,7 +1227,7 @@ class DateTimeRange {
619
1227
  this.formDisabled.set(isDisabled);
620
1228
  }
621
1229
  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: [
1230
+ 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
1231
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DateTimeRange), multi: true },
624
1232
  ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
625
1233
  }
@@ -634,7 +1242,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
634
1242
  ],
635
1243
  template: '',
636
1244
  }]
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 }] }] } });
1245
+ }], 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
1246
 
639
1247
  const EMPTY = { start: null, end: null, from: null, to: null };
640
1248
  /**
@@ -643,15 +1251,29 @@ const EMPTY = { start: null, end: null, from: null, to: null };
643
1251
  */
644
1252
  class DailyRange {
645
1253
  constructor() {
1254
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1255
+ this.defaults = inject(TZSLOT_DEFAULTS);
646
1256
  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 */ []));
1257
+ /**
1258
+ * An IANA identifier. Required in spirit: given here, it wins; left out, it
1259
+ * is the zone provideTzslot() settled for the application, and only when
1260
+ * nothing was settled anywhere does it fall back to the browser's — which
1261
+ * is a guess, and the one thing this library exists not to do silently.
1262
+ */
1263
+ this.timeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "timeZone" }] : /* istanbul ignore next */ []));
649
1264
  this.stepMinutes = input(30, ...(ngDevMode ? [{ debugName: "stepMinutes" }] : /* istanbul ignore next */ []));
1265
+ /** 'input' (default) for two compact fields, 'list' for times to click. */
1266
+ this.timeLayout = input('input', ...(ngDevMode ? [{ debugName: "timeLayout" }] : /* istanbul ignore next */ []));
1267
+ /** 12-hour fields with an AM/PM button; the locale decides when unset. */
1268
+ this.hour12 = input(undefined, ...(ngDevMode ? [{ debugName: "hour12" }] : /* istanbul ignore next */ []));
1269
+ /** With timeLayout 'columns': minutes between the options. Every minute by default. */
1270
+ this.minuteStep = input(1, ...(ngDevMode ? [{ debugName: "minuteStep" }] : /* istanbul ignore next */ []));
650
1271
  /** The first and last times offered. */
651
1272
  this.minTime = input(undefined, ...(ngDevMode ? [{ debugName: "minTime" }] : /* istanbul ignore next */ []));
652
1273
  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 */ []));
1274
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
1275
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
1276
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
655
1277
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
656
1278
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
657
1279
  this.isDateDisabled = input(undefined, ...(ngDevMode ? [{ debugName: "isDateDisabled" }] : /* istanbul ignore next */ []));
@@ -666,6 +1288,9 @@ class DailyRange {
666
1288
  value: this.value(),
667
1289
  timeZone: this.timeZone(),
668
1290
  stepMinutes: this.stepMinutes(),
1291
+ timeLayout: this.timeLayout(),
1292
+ hour12: this.hour12(),
1293
+ minuteStep: this.minuteStep(),
669
1294
  minTime: this.minTime(),
670
1295
  maxTime: this.maxTime(),
671
1296
  firstDayOfWeek: this.firstDayOfWeek(),
@@ -707,6 +1332,11 @@ class DailyRange {
707
1332
  clear() {
708
1333
  this.range.clear();
709
1334
  }
1335
+ /**
1336
+ * A pattern, not a moment: two days and the clock faces repeated over them.
1337
+ * `valueAs` has nothing to convert here, which is why this component does
1338
+ * not take it — see the note on TzslotDefaults.
1339
+ */
710
1340
  writeValue(value) {
711
1341
  this.value.set(value ?? EMPTY);
712
1342
  }
@@ -720,7 +1350,7 @@ class DailyRange {
720
1350
  this.formDisabled.set(isDisabled);
721
1351
  }
722
1352
  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: [
1353
+ 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
1354
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => DailyRange), multi: true },
725
1355
  ], ngImport: i0, template: '', isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
726
1356
  }
@@ -735,7 +1365,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
735
1365
  ],
736
1366
  template: '',
737
1367
  }]
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 }] }] } });
1368
+ }], 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
1369
 
740
1370
  /**
741
1371
  * `<tz-multi-date>` — several days, not necessarily next to each other, from
@@ -743,12 +1373,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
743
1373
  */
744
1374
  class MultiDate {
745
1375
  constructor() {
1376
+ /** Set once for the application with provideTzslot(); a binding still wins. */
1377
+ this.defaults = inject(TZSLOT_DEFAULTS);
746
1378
  /** The chosen days, in date order. Two-way: `[(value)]`. */
747
1379
  this.value = model([], ...(ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []));
748
1380
  /** Once this many are chosen, the other days stop taking clicks. */
749
1381
  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 */ []));
1382
+ /** Left out, the locale decides — see `provideTzslot` to settle it once. */
1383
+ this.firstDayOfWeek = input(this.defaults.firstDayOfWeek, ...(ngDevMode ? [{ debugName: "firstDayOfWeek" }] : /* istanbul ignore next */ []));
1384
+ this.locale = input(this.defaults.locale, ...(ngDevMode ? [{ debugName: "locale" }] : /* istanbul ignore next */ []));
752
1385
  this.min = input(null, ...(ngDevMode ? [{ debugName: "min" }] : /* istanbul ignore next */ []));
753
1386
  this.max = input(null, ...(ngDevMode ? [{ debugName: "max" }] : /* istanbul ignore next */ []));
754
1387
  this.disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
@@ -756,11 +1389,13 @@ class MultiDate {
756
1389
  this.today = input(Temporal.Now.plainDateISO(), ...(ngDevMode ? [{ debugName: "today" }] : /* istanbul ignore next */ []));
757
1390
  this.view = model('days', ...(ngDevMode ? [{ debugName: "view" }] : /* istanbul ignore next */ []));
758
1391
  this.renderCell = input(undefined, ...(ngDevMode ? [{ debugName: "renderCell" }] : /* istanbul ignore next */ []));
1392
+ /** A column of ISO week numbers down the left. */
1393
+ this.weekNumbers = input(false, ...(ngDevMode ? [{ debugName: "weekNumbers" }] : /* istanbul ignore next */ []));
759
1394
  this.buttons = input([], ...(ngDevMode ? [{ debugName: "buttons" }] : /* istanbul ignore next */ []));
760
1395
  /** 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 */ []));
1396
+ this.valueAs = input(this.defaults.valueAs ?? 'temporal', ...(ngDevMode ? [{ debugName: "valueAs" }] : /* istanbul ignore next */ []));
762
1397
  /** 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 */ []));
1398
+ this.valueTimeZone = input(this.defaults.timeZone ?? Temporal.Now.timeZoneId(), ...(ngDevMode ? [{ debugName: "valueTimeZone" }] : /* istanbul ignore next */ []));
764
1399
  this.formDisabled = signal(false, ...(ngDevMode ? [{ debugName: "formDisabled" }] : /* istanbul ignore next */ []));
765
1400
  this.host = inject(ElementRef).nativeElement;
766
1401
  this.messages = inject(TZSLOT_MESSAGES);
@@ -779,6 +1414,7 @@ class MultiDate {
779
1414
  today: this.today(),
780
1415
  renderCell: this.renderCell(),
781
1416
  buttons: this.buttons(),
1417
+ weekNumbers: this.weekNumbers(),
782
1418
  messages: this.messages,
783
1419
  }), ...(ngDevMode ? [{ debugName: "settings" }] : /* istanbul ignore next */ []));
784
1420
  this.calendar = createMultiDate(this.host, {
@@ -836,7 +1472,7 @@ class MultiDate {
836
1472
  this.formDisabled.set(isDisabled);
837
1473
  }
838
1474
  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: [
1475
+ 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
1476
  { provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MultiDate), multi: true },
841
1477
  ], 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
1478
  <span #prev hidden><ng-content select="[tzPrev]" /></span>
@@ -857,7 +1493,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
857
1493
  <span #next hidden><ng-content select="[tzNext]" /></span>
858
1494
  `,
859
1495
  }]
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 }] }] } });
1496
+ }], 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
1497
 
862
1498
  /**
863
1499
  * @tzslot/ui — Angular components over the core.
@@ -871,5 +1507,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.23", ngImpo
871
1507
  * Generated bundle index. Do not edit.
872
1508
  */
873
1509
 
874
- export { Calendar, DailyRange, DateField, DateRange, DateTimeRange, MultiDate, TZSLOT_MESSAGES, TimeSlotPicker, provideTzslotMessages };
1510
+ export { Calendar, DailyRange, DateField, DateRange, DateTimeField, DateTimeRange, MultiDate, RangeField, TZSLOT_DEFAULTS, TZSLOT_MESSAGES, TimeSlotPicker, pairIn, pairOut, provideTzslot, provideTzslotMessages };
875
1511
  //# sourceMappingURL=tzslot-angular.mjs.map