@egose/shadcn-theme-ng-tw 0.6.0 → 0.6.2
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.
- package/README.md +119 -1
- package/autocomplete/fesm2022/autocomplete.mjs +14 -4
- package/autocomplete/types/autocomplete.d.ts +4 -1
- package/checkbox/README.md +6 -2
- package/checkbox/fesm2022/checkbox.mjs +15 -9
- package/checkbox/types/checkbox.d.ts +6 -4
- package/combobox/fesm2022/combobox.mjs +22 -6
- package/combobox/types/combobox.d.ts +8 -2
- package/data-table/README.md +11 -1
- package/data-table/fesm2022/data-table.mjs +76 -26
- package/data-table/types/data-table.d.ts +25 -6
- package/date-picker/README.md +41 -9
- package/date-picker/fesm2022/date-picker.mjs +265 -59
- package/date-picker/types/date-picker.d.ts +58 -27
- package/form-autocomplete/README.md +4 -2
- package/form-autocomplete/fesm2022/form-autocomplete.mjs +33 -8
- package/form-autocomplete/types/form-autocomplete.d.ts +9 -3
- package/form-combobox/README.md +4 -2
- package/form-combobox/fesm2022/form-combobox.mjs +65 -14
- package/form-combobox/types/form-combobox.d.ts +10 -3
- package/form-input-otp/README.md +7 -5
- package/form-input-otp/fesm2022/form-input-otp.mjs +28 -14
- package/form-input-otp/types/form-input-otp.d.ts +9 -3
- package/form-searchable-multiselect/README.md +15 -1
- package/form-searchable-multiselect/fesm2022/form-searchable-multiselect.mjs +23 -3
- package/form-searchable-multiselect/types/form-searchable-multiselect.d.ts +9 -1
- package/form-slider/README.md +3 -1
- package/form-slider/fesm2022/form-slider.mjs +21 -6
- package/form-slider/types/form-slider.d.ts +9 -3
- package/form-toggle/README.md +22 -18
- package/form-toggle/fesm2022/form-toggle.mjs +25 -8
- package/form-toggle/types/form-toggle.d.ts +6 -2
- package/input-otp/README.md +33 -9
- package/input-otp/fesm2022/input-otp.mjs +127 -11
- package/input-otp/types/input-otp.d.ts +24 -4
- package/package.json +1 -1
- package/pagination/README.md +21 -12
- package/pagination/fesm2022/pagination.mjs +83 -75
- package/pagination/types/pagination.d.ts +21 -8
- package/phone-input/README.md +16 -0
- package/phone-input/fesm2022/phone-input.mjs +41 -3
- package/phone-input/types/phone-input.d.ts +5 -2
- package/searchable-multiselect/README.md +62 -40
- package/searchable-multiselect/fesm2022/searchable-multiselect.mjs +97 -36
- package/searchable-multiselect/types/searchable-multiselect.d.ts +23 -6
- package/slider/fesm2022/slider.mjs +15 -5
- package/slider/types/slider.d.ts +6 -2
- package/stepper/README.md +39 -19
- package/stepper/fesm2022/stepper.mjs +71 -17
- package/stepper/types/stepper.d.ts +12 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, inject, input, booleanAttribute, computed, ChangeDetectionStrategy, Component, forwardRef, viewChild, contentChild,
|
|
2
|
+
import { InjectionToken, inject, signal, Injectable, linkedSignal, Directive, input, booleanAttribute, computed, ChangeDetectionStrategy, Component, forwardRef, viewChild, contentChild, output, ElementRef, effect, numberAttribute, untracked, NgModule } from '@angular/core';
|
|
3
3
|
import { NgIcon, provideIcons } from '@ng-icons/core';
|
|
4
4
|
import { lucideX, lucideCalendar, lucideChevronDown } from '@ng-icons/lucide';
|
|
5
5
|
import { BrnDateInput, provideBrnDatePickerTrigger, BrnDatePickerTriggerToken, provideBrnDatePicker, injectBrnDatePicker } from '@spartan-ng/brain/date-picker';
|
|
@@ -10,6 +10,8 @@ import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
|
10
10
|
import * as i1$1 from '@spartan-ng/brain/field';
|
|
11
11
|
import { provideBrnLabelable, BrnFieldControl, BrnFieldControlDescribedBy } from '@spartan-ng/brain/field';
|
|
12
12
|
import { BrnPopover } from '@spartan-ng/brain/popover';
|
|
13
|
+
import { injectDateAdapter } from '@spartan-ng/brain/date-time';
|
|
14
|
+
import { BrnCalendar, BrnCalendarMulti, BrnCalendarRange } from '@spartan-ng/brain/calendar';
|
|
13
15
|
import * as i3 from '@egose/shadcn-theme-ng-tw/calendar';
|
|
14
16
|
import { HlmCalendar, HlmCalendarMulti, HlmCalendarRange, HlmCalendarImports } from '@egose/shadcn-theme-ng-tw/calendar';
|
|
15
17
|
import * as i2 from '@egose/shadcn-theme-ng-tw/popover';
|
|
@@ -68,7 +70,100 @@ function injectHlmDatePickerMultiConfig() {
|
|
|
68
70
|
return injectedConfig ? injectedConfig : getDefaultConfig$3();
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
|
|
73
|
+
/** Internal synchronization for explicit writes, including writes of the same value. */
|
|
74
|
+
class HlmDatePickerCommitState {
|
|
75
|
+
revision = signal(0, /* @ts-ignore */
|
|
76
|
+
...(ngDevMode ? [{ debugName: "revision" }] : /* istanbul ignore next */ []));
|
|
77
|
+
changed() {
|
|
78
|
+
this.revision.update((revision) => revision + 1);
|
|
79
|
+
}
|
|
80
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDatePickerCommitState, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
81
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDatePickerCommitState });
|
|
82
|
+
}
|
|
83
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDatePickerCommitState, decorators: [{
|
|
84
|
+
type: Injectable
|
|
85
|
+
}] });
|
|
86
|
+
/** Match the calendar's inclusive whole-day bounds with the configured adapter. */
|
|
87
|
+
function isSelectableDate(adapter, value, min, max) {
|
|
88
|
+
return (value != null &&
|
|
89
|
+
Number.isFinite(adapter.getTime(value)) &&
|
|
90
|
+
(min == null || !adapter.isBefore(value, adapter.startOfDay(min))) &&
|
|
91
|
+
(max == null || !adapter.isAfter(value, adapter.endOfDay(max))));
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/** Internal input lifecycle shared by the single, range and multi pickers. */
|
|
95
|
+
class HlmConstrainedDateInput extends BrnDateInput {
|
|
96
|
+
_commitState = inject(HlmDatePickerCommitState);
|
|
97
|
+
_inputValue = linkedSignal({ ...(ngDevMode ? { debugName: "_inputValue" } : /* istanbul ignore next */ {}), source: () => ({
|
|
98
|
+
revision: this._commitState.revision(),
|
|
99
|
+
formatted: this._datePicker.formattedDate(),
|
|
100
|
+
value: this._datePicker.value?.(),
|
|
101
|
+
inputValue: this.inputValue(),
|
|
102
|
+
}),
|
|
103
|
+
computation: (source, previous) => {
|
|
104
|
+
if (!previous)
|
|
105
|
+
return source.formatted ?? source.inputValue;
|
|
106
|
+
if (source.revision !== previous.source.revision ||
|
|
107
|
+
source.value !== previous.source.value ||
|
|
108
|
+
source.formatted !== previous.source.formatted)
|
|
109
|
+
return source.formatted ?? '';
|
|
110
|
+
if (source.inputValue !== previous.source.inputValue)
|
|
111
|
+
return source.inputValue;
|
|
112
|
+
return previous.value;
|
|
113
|
+
} });
|
|
114
|
+
/** Rejected text stays invalid until a successful commit, clear, or external value write. */
|
|
115
|
+
inputInvalid = linkedSignal(() => {
|
|
116
|
+
this._commitState.revision();
|
|
117
|
+
this._datePicker.value?.();
|
|
118
|
+
this.inputValue();
|
|
119
|
+
return false;
|
|
120
|
+
}, /* @ts-ignore */
|
|
121
|
+
...(ngDevMode ? [{ debugName: "inputInvalid" }] : /* istanbul ignore next */ []));
|
|
122
|
+
_commitDate() {
|
|
123
|
+
if (this._disabled() || this.readonly())
|
|
124
|
+
return;
|
|
125
|
+
const text = this._inputValue();
|
|
126
|
+
const parsed = text ? this.parseValue(text) : null;
|
|
127
|
+
const picker = this._datePicker;
|
|
128
|
+
const accepted = (!text || parsed != null) && picker.updateDate(parsed);
|
|
129
|
+
this.inputInvalid.set(!accepted);
|
|
130
|
+
this._datePicker.touched?.();
|
|
131
|
+
}
|
|
132
|
+
_handleBlur() {
|
|
133
|
+
if (this._disabled() || this.readonly())
|
|
134
|
+
return;
|
|
135
|
+
this._commitDate();
|
|
136
|
+
if (!this.inputInvalid())
|
|
137
|
+
this._inputValue.set(this._datePicker.formattedDate() ?? '');
|
|
138
|
+
}
|
|
139
|
+
_handleEnter(event) {
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
if (this._disabled() || this.readonly())
|
|
142
|
+
return;
|
|
143
|
+
this._commitDate();
|
|
144
|
+
if (!this.inputInvalid()) {
|
|
145
|
+
this._popover().close();
|
|
146
|
+
this._handleFocus();
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
_handleFocus() {
|
|
150
|
+
if (!this.inputInvalid())
|
|
151
|
+
super._handleFocus();
|
|
152
|
+
}
|
|
153
|
+
_clear() {
|
|
154
|
+
if (this._disabled() || this.readonly())
|
|
155
|
+
return;
|
|
156
|
+
this._inputValue.set('');
|
|
157
|
+
this._commitDate();
|
|
158
|
+
}
|
|
159
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmConstrainedDateInput, deps: null, target: i0.ɵɵFactoryTarget.Directive });
|
|
160
|
+
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "22.1.3", type: HlmConstrainedDateInput, isStandalone: true, usesInheritance: true, ngImport: i0 });
|
|
161
|
+
}
|
|
162
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmConstrainedDateInput, decorators: [{
|
|
163
|
+
type: Directive
|
|
164
|
+
}] });
|
|
165
|
+
|
|
166
|
+
class HlmDateMultiInput extends HlmConstrainedDateInput {
|
|
72
167
|
_config = injectHlmDatePickerMultiConfig();
|
|
73
168
|
/** Native `name` attribute forwarded to the inner `<input>`. */
|
|
74
169
|
name = input(undefined, /* @ts-ignore */
|
|
@@ -91,9 +186,9 @@ class HlmDateMultiInput extends BrnDateInput {
|
|
|
91
186
|
classes(() => [this.userClass()]);
|
|
92
187
|
}
|
|
93
188
|
/**
|
|
94
|
-
* Parses input text into dates. Return `null` for invalid input
|
|
95
|
-
*
|
|
96
|
-
*
|
|
189
|
+
* Parses input text into dates. Return `null` for invalid input. Rejected
|
|
190
|
+
* text stays editable and aria-invalid; the committed value is preserved.
|
|
191
|
+
* Empty text explicitly clears on blur/Enter.
|
|
97
192
|
*
|
|
98
193
|
* Defaults to `parseDate` from `HlmDatePickerMultiConfig`.
|
|
99
194
|
*/
|
|
@@ -126,7 +221,8 @@ class HlmDateMultiInput extends BrnDateInput {
|
|
|
126
221
|
[placeholder]="placeholder()"
|
|
127
222
|
[readonly]="readonly()"
|
|
128
223
|
[disabled]="_disabled()"
|
|
129
|
-
[
|
|
224
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
225
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
130
226
|
[class]="$inputClass()"
|
|
131
227
|
(click)="_handleClick()"
|
|
132
228
|
(keydown.arrowDown)="_open()"
|
|
@@ -180,7 +276,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
180
276
|
[placeholder]="placeholder()"
|
|
181
277
|
[readonly]="readonly()"
|
|
182
278
|
[disabled]="_disabled()"
|
|
183
|
-
[
|
|
279
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
280
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
184
281
|
[class]="$inputClass()"
|
|
185
282
|
(click)="_handleClick()"
|
|
186
283
|
(keydown.arrowDown)="_open()"
|
|
@@ -244,6 +341,11 @@ const HLM_DATE_PICKER_VALUE_ACCESSOR = {
|
|
|
244
341
|
};
|
|
245
342
|
class HlmDatePicker {
|
|
246
343
|
_config = injectHlmDatePickerConfig();
|
|
344
|
+
_dateAdapter = injectDateAdapter();
|
|
345
|
+
_commitState = inject(HlmDatePickerCommitState);
|
|
346
|
+
_calendar = viewChild((BrnCalendar), /* @ts-ignore */
|
|
347
|
+
...(ngDevMode ? [{ debugName: "_calendar" }] : /* istanbul ignore next */ []));
|
|
348
|
+
_restoringCalendar = false;
|
|
247
349
|
popover = viewChild.required(BrnPopover, /* @ts-ignore */
|
|
248
350
|
...(ngDevMode ? [{ debugName: "popover" }] : /* istanbul ignore next */ []));
|
|
249
351
|
_trigger = contentChild(BrnDatePickerTriggerToken, /* @ts-ignore */
|
|
@@ -305,30 +407,46 @@ class HlmDatePicker {
|
|
|
305
407
|
this._onTouched?.();
|
|
306
408
|
}
|
|
307
409
|
_handleChange(value) {
|
|
308
|
-
if (this.
|
|
410
|
+
if (this._restoringCalendar)
|
|
309
411
|
return;
|
|
310
|
-
this.updateDate(value ?? null)
|
|
412
|
+
if (!this.updateDate(value ?? null)) {
|
|
413
|
+
// Brain model signals have already changed before their output fires.
|
|
414
|
+
this._restoringCalendar = true;
|
|
415
|
+
try {
|
|
416
|
+
this._calendar()?.date.set(this._mutableDate());
|
|
417
|
+
}
|
|
418
|
+
finally {
|
|
419
|
+
this._restoringCalendar = false;
|
|
420
|
+
}
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
311
423
|
if (this.autoCloseOnSelect()) {
|
|
312
424
|
this._popoverState.set('closed');
|
|
313
425
|
}
|
|
314
426
|
}
|
|
315
427
|
/**
|
|
316
|
-
* Commit a
|
|
317
|
-
*
|
|
318
|
-
*
|
|
319
|
-
* is parsing user-entered values while typing.
|
|
428
|
+
* Commit a user value (null clears). Returns false without changing/emitting
|
|
429
|
+
* the model when disabled or when the raw/transformed date is invalid or
|
|
430
|
+
* outside the adapter's inclusive whole-day min/max bounds.
|
|
320
431
|
*/
|
|
321
432
|
updateDate(value) {
|
|
322
433
|
if (this.disabledState())
|
|
323
|
-
return;
|
|
434
|
+
return false;
|
|
435
|
+
if (value != null && !isSelectableDate(this._dateAdapter, value, this.min(), this.max()))
|
|
436
|
+
return false;
|
|
324
437
|
const transformedDate = value != null ? this.transformDate()(value) : undefined;
|
|
438
|
+
if (value != null && !isSelectableDate(this._dateAdapter, transformedDate, this.min(), this.max()))
|
|
439
|
+
return false;
|
|
325
440
|
this._mutableDate.set(transformedDate);
|
|
441
|
+
this._commitState.changed();
|
|
326
442
|
this._onChange?.(transformedDate ?? null);
|
|
327
443
|
this.dateChange.emit(transformedDate ?? null);
|
|
444
|
+
return true;
|
|
328
445
|
}
|
|
329
|
-
/**
|
|
446
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
330
447
|
writeValue(value) {
|
|
331
|
-
this._mutableDate.set(value ? this.transformDate()(value) : undefined);
|
|
448
|
+
this._mutableDate.set(value != null ? this.transformDate()(value) : undefined);
|
|
449
|
+
this._commitState.changed();
|
|
332
450
|
}
|
|
333
451
|
registerOnChange(fn) {
|
|
334
452
|
this._onChange = fn;
|
|
@@ -350,11 +468,17 @@ class HlmDatePicker {
|
|
|
350
468
|
}
|
|
351
469
|
reset() {
|
|
352
470
|
this._mutableDate.set(undefined);
|
|
471
|
+
this._commitState.changed();
|
|
353
472
|
this._onChange?.(null);
|
|
354
473
|
this.dateChange.emit(null);
|
|
355
474
|
}
|
|
356
475
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
357
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.3", type: HlmDatePicker, isStandalone: true, selector: "hlm-date-picker", inputs: { captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", 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 }, wrapperDisabled: { classPropertyName: "wrapperDisabled", publicName: "wrapperDisabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, defaultFocusedDate: { classPropertyName: "defaultFocusedDate", publicName: "defaultFocusedDate", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "tw:block tw:w-full tw:min-w-0 tw:max-w-full" }, providers: [
|
|
476
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.3", type: HlmDatePicker, isStandalone: true, selector: "hlm-date-picker", inputs: { captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", 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 }, wrapperDisabled: { classPropertyName: "wrapperDisabled", publicName: "wrapperDisabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, defaultFocusedDate: { classPropertyName: "defaultFocusedDate", publicName: "defaultFocusedDate", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnSelect: { classPropertyName: "autoCloseOnSelect", publicName: "autoCloseOnSelect", isSignal: true, isRequired: false, transformFunction: null }, formatDate: { classPropertyName: "formatDate", publicName: "formatDate", isSignal: true, isRequired: false, transformFunction: null }, transformDate: { classPropertyName: "transformDate", publicName: "transformDate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "tw:block tw:w-full tw:min-w-0 tw:max-w-full" }, providers: [
|
|
477
|
+
HlmDatePickerCommitState,
|
|
478
|
+
HLM_DATE_PICKER_VALUE_ACCESSOR,
|
|
479
|
+
provideBrnDatePicker(HlmDatePicker),
|
|
480
|
+
provideBrnLabelable(HlmDatePicker),
|
|
481
|
+
], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_calendar", first: true, predicate: (BrnCalendar), descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
|
|
358
482
|
<hlm-popover sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
|
|
359
483
|
<ng-content />
|
|
360
484
|
|
|
@@ -380,7 +504,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
380
504
|
args: [{
|
|
381
505
|
selector: 'hlm-date-picker',
|
|
382
506
|
imports: [HlmPopoverImports, HlmCalendar],
|
|
383
|
-
providers: [
|
|
507
|
+
providers: [
|
|
508
|
+
HlmDatePickerCommitState,
|
|
509
|
+
HLM_DATE_PICKER_VALUE_ACCESSOR,
|
|
510
|
+
provideBrnDatePicker(HlmDatePicker),
|
|
511
|
+
provideBrnLabelable(HlmDatePicker),
|
|
512
|
+
],
|
|
384
513
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
385
514
|
hostDirectives: [BrnFieldControl],
|
|
386
515
|
host: { class: 'tw:block tw:w-full tw:min-w-0 tw:max-w-full' },
|
|
@@ -405,7 +534,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
405
534
|
</hlm-popover>
|
|
406
535
|
`,
|
|
407
536
|
}]
|
|
408
|
-
}], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", 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 }] }], wrapperDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperDisabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], defaultFocusedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFocusedDate", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
537
|
+
}], propDecorators: { _calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCalendar), { isSignal: true }] }], popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", 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 }] }], wrapperDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "wrapperDisabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], defaultFocusedDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "defaultFocusedDate", required: false }] }], autoCloseOnSelect: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnSelect", required: false }] }], formatDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDate", required: false }] }], transformDate: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDate", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
409
538
|
|
|
410
539
|
class HlmDatePickerAnchor {
|
|
411
540
|
_host = inject(ElementRef, { host: true });
|
|
@@ -427,7 +556,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
427
556
|
args: [{ selector: '[hlmDatePickerAnchor]' }]
|
|
428
557
|
}], ctorParameters: () => [], propDecorators: { hlmDatePickerAnchorForInput: [{ type: i0.Input, args: [{ isSignal: true, alias: "hlmDatePickerAnchorFor", required: false }] }] } });
|
|
429
558
|
|
|
430
|
-
class HlmDatePickerInput extends
|
|
559
|
+
class HlmDatePickerInput extends HlmConstrainedDateInput {
|
|
431
560
|
_config = injectHlmDatePickerConfig();
|
|
432
561
|
ariaLabel = input(undefined, /* @ts-ignore */
|
|
433
562
|
...(ngDevMode ? [{ debugName: "ariaLabel" }] : /* istanbul ignore next */ []));
|
|
@@ -451,8 +580,8 @@ class HlmDatePickerInput extends BrnDateInput {
|
|
|
451
580
|
}
|
|
452
581
|
/**
|
|
453
582
|
* Parses input text into a date value. Return `null` for invalid
|
|
454
|
-
* input
|
|
455
|
-
*
|
|
583
|
+
* input. Rejected text stays editable and aria-invalid; the committed value
|
|
584
|
+
* is preserved. Empty text explicitly clears on blur/Enter.
|
|
456
585
|
*
|
|
457
586
|
* Defaults to `parseDate` from `HlmDatePickerConfig`.
|
|
458
587
|
*/
|
|
@@ -485,7 +614,8 @@ class HlmDatePickerInput extends BrnDateInput {
|
|
|
485
614
|
[placeholder]="placeholder()"
|
|
486
615
|
[readonly]="readonly()"
|
|
487
616
|
[disabled]="_disabled()"
|
|
488
|
-
[
|
|
617
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
618
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
489
619
|
[class]="$inputClass()"
|
|
490
620
|
(click)="_handleClick()"
|
|
491
621
|
(keydown.arrowDown)="_open()"
|
|
@@ -539,7 +669,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
539
669
|
[placeholder]="placeholder()"
|
|
540
670
|
[readonly]="readonly()"
|
|
541
671
|
[disabled]="_disabled()"
|
|
542
|
-
[
|
|
672
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
673
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
543
674
|
[class]="$inputClass()"
|
|
544
675
|
(click)="_handleClick()"
|
|
545
676
|
(keydown.arrowDown)="_open()"
|
|
@@ -582,6 +713,11 @@ const HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR = {
|
|
|
582
713
|
};
|
|
583
714
|
class HlmDatePickerMulti {
|
|
584
715
|
_config = injectHlmDatePickerMultiConfig();
|
|
716
|
+
_dateAdapter = injectDateAdapter();
|
|
717
|
+
_commitState = inject(HlmDatePickerCommitState);
|
|
718
|
+
_calendar = viewChild((BrnCalendarMulti), /* @ts-ignore */
|
|
719
|
+
...(ngDevMode ? [{ debugName: "_calendar" }] : /* istanbul ignore next */ []));
|
|
720
|
+
_restoringCalendar = false;
|
|
585
721
|
popover = viewChild.required(BrnPopover, /* @ts-ignore */
|
|
586
722
|
...(ngDevMode ? [{ debugName: "popover" }] : /* istanbul ignore next */ []));
|
|
587
723
|
_trigger = contentChild(BrnDatePickerTriggerToken, /* @ts-ignore */
|
|
@@ -595,7 +731,7 @@ class HlmDatePickerMulti {
|
|
|
595
731
|
/** The maximum date that can be selected. */
|
|
596
732
|
max = input(/* @ts-ignore */
|
|
597
733
|
...(ngDevMode ? [undefined, { debugName: "max" }] : /* istanbul ignore next */ []));
|
|
598
|
-
/**
|
|
734
|
+
/** Deselection floor; selection can grow from empty below this count. Explicit clear is allowed. */
|
|
599
735
|
minSelection = input(undefined, { ...(ngDevMode ? { debugName: "minSelection" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
600
736
|
/** The maximum selectable dates. */
|
|
601
737
|
maxSelection = input(undefined, { ...(ngDevMode ? { debugName: "maxSelection" } : /* istanbul ignore next */ {}), transform: numberAttribute });
|
|
@@ -643,37 +779,58 @@ class HlmDatePickerMulti {
|
|
|
643
779
|
this._onTouched?.();
|
|
644
780
|
}
|
|
645
781
|
_handleChange(value) {
|
|
646
|
-
if (value === undefined)
|
|
782
|
+
if (this._restoringCalendar || value === undefined)
|
|
647
783
|
return;
|
|
648
|
-
if (this.
|
|
784
|
+
if (!this.updateDate(value)) {
|
|
785
|
+
// Restore the calendar's already-mutated model without a second user commit.
|
|
786
|
+
this._restoringCalendar = true;
|
|
787
|
+
try {
|
|
788
|
+
this._calendar()?.date.set(this._mutableDate());
|
|
789
|
+
}
|
|
790
|
+
finally {
|
|
791
|
+
this._restoringCalendar = false;
|
|
792
|
+
}
|
|
649
793
|
return;
|
|
650
|
-
|
|
651
|
-
this._mutableDate.set(transformedDate);
|
|
652
|
-
this._onChange?.(transformedDate);
|
|
653
|
-
this.dateChange.emit(transformedDate);
|
|
794
|
+
}
|
|
654
795
|
if (this.autoCloseOnMaxSelection() && this._mutableDate()?.length === this.maxSelection()) {
|
|
655
796
|
this._popoverState.set('closed');
|
|
656
797
|
}
|
|
657
798
|
}
|
|
658
799
|
/**
|
|
659
|
-
* Commit dates
|
|
660
|
-
*
|
|
661
|
-
*
|
|
800
|
+
* Commit user dates, validating raw and transformed dates/counts. Returns
|
|
801
|
+
* false without changing/emitting on rejection. Min selection prevents
|
|
802
|
+
* reductions below the floor, but permits growth from empty. Null explicitly
|
|
803
|
+
* clears (emits []), bypassing the selection floor and transform.
|
|
662
804
|
*/
|
|
663
805
|
updateDate(value) {
|
|
664
806
|
if (this._disabled())
|
|
665
|
-
return;
|
|
807
|
+
return false;
|
|
808
|
+
if (value && !this._isSelectionAllowed(value))
|
|
809
|
+
return false;
|
|
666
810
|
const transformedDate = value ? this.transformDates()(value) : undefined;
|
|
811
|
+
if (value && (!transformedDate || !this._isSelectionAllowed(transformedDate)))
|
|
812
|
+
return false;
|
|
667
813
|
this._mutableDate.set(transformedDate);
|
|
814
|
+
this._commitState.changed();
|
|
668
815
|
this._onChange?.(transformedDate ?? []);
|
|
669
816
|
this.dateChange.emit(transformedDate ?? []);
|
|
817
|
+
return true;
|
|
818
|
+
}
|
|
819
|
+
_isSelectionAllowed(dates) {
|
|
820
|
+
const min = this.minSelection();
|
|
821
|
+
const max = this.maxSelection();
|
|
822
|
+
const currentCount = this._mutableDate()?.length ?? 0;
|
|
823
|
+
return (!(max != null && dates.length > max) &&
|
|
824
|
+
!(min != null && dates.length < min && dates.length < currentCount) &&
|
|
825
|
+
dates.every((date) => isSelectableDate(this._dateAdapter, date, this.min(), this.max())));
|
|
670
826
|
}
|
|
671
827
|
touched() {
|
|
672
828
|
this._onTouched?.();
|
|
673
829
|
}
|
|
674
|
-
/**
|
|
830
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
675
831
|
writeValue(value) {
|
|
676
832
|
this._mutableDate.set(value ? this.transformDates()(value) : undefined);
|
|
833
|
+
this._commitState.changed();
|
|
677
834
|
}
|
|
678
835
|
registerOnChange(fn) {
|
|
679
836
|
this._onChange = fn;
|
|
@@ -692,15 +849,17 @@ class HlmDatePickerMulti {
|
|
|
692
849
|
}
|
|
693
850
|
reset() {
|
|
694
851
|
this._mutableDate.set(undefined);
|
|
852
|
+
this._commitState.changed();
|
|
695
853
|
this._onChange?.([]);
|
|
696
854
|
this.dateChange.emit([]);
|
|
697
855
|
}
|
|
698
856
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDatePickerMulti, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
699
857
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.3", type: HlmDatePickerMulti, isStandalone: true, selector: "hlm-date-picker-multi", inputs: { captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", 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 }, minSelection: { classPropertyName: "minSelection", publicName: "minSelection", isSignal: true, isRequired: false, transformFunction: null }, maxSelection: { classPropertyName: "maxSelection", publicName: "maxSelection", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnMaxSelection: { classPropertyName: "autoCloseOnMaxSelection", publicName: "autoCloseOnMaxSelection", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [
|
|
858
|
+
HlmDatePickerCommitState,
|
|
700
859
|
HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR,
|
|
701
860
|
provideBrnDatePicker(HlmDatePickerMulti),
|
|
702
861
|
provideBrnLabelable(HlmDatePickerMulti),
|
|
703
|
-
], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
|
|
862
|
+
], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_calendar", first: true, predicate: (BrnCalendarMulti), descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
|
|
704
863
|
<hlm-popover sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
|
|
705
864
|
<ng-content />
|
|
706
865
|
|
|
@@ -728,6 +887,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
728
887
|
selector: 'hlm-date-picker-multi',
|
|
729
888
|
imports: [HlmPopoverImports, HlmCalendarMulti],
|
|
730
889
|
providers: [
|
|
890
|
+
HlmDatePickerCommitState,
|
|
731
891
|
HLM_DATE_PICKER_MUTLI_VALUE_ACCESSOR,
|
|
732
892
|
provideBrnDatePicker(HlmDatePickerMulti),
|
|
733
893
|
provideBrnLabelable(HlmDatePickerMulti),
|
|
@@ -757,7 +917,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
757
917
|
</hlm-popover>
|
|
758
918
|
`,
|
|
759
919
|
}]
|
|
760
|
-
}], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], minSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelection", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnMaxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnMaxSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
920
|
+
}], propDecorators: { _calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCalendarMulti), { isSignal: true }] }], popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", required: false }] }], min: [{ type: i0.Input, args: [{ isSignal: true, alias: "min", required: false }] }], max: [{ type: i0.Input, args: [{ isSignal: true, alias: "max", required: false }] }], minSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "minSelection", required: false }] }], maxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxSelection", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnMaxSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnMaxSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
761
921
|
|
|
762
922
|
class HlmDatePickerTrigger {
|
|
763
923
|
static _nextId = 0;
|
|
@@ -885,7 +1045,7 @@ function getDefaultConfig$1() {
|
|
|
885
1045
|
if (isNaN(start.getTime()))
|
|
886
1046
|
return null;
|
|
887
1047
|
const end = parts.length === 2 ? new Date(parts[1]) : start;
|
|
888
|
-
return
|
|
1048
|
+
return isNaN(end.getTime()) ? null : [start, end];
|
|
889
1049
|
},
|
|
890
1050
|
};
|
|
891
1051
|
}
|
|
@@ -898,7 +1058,7 @@ function injectHlmDateRangePickerConfig() {
|
|
|
898
1058
|
return injectedConfig ? injectedConfig : getDefaultConfig$1();
|
|
899
1059
|
}
|
|
900
1060
|
|
|
901
|
-
class HlmDateRangeInput extends
|
|
1061
|
+
class HlmDateRangeInput extends HlmConstrainedDateInput {
|
|
902
1062
|
_config = injectHlmDateRangePickerConfig();
|
|
903
1063
|
/** Native `name` attribute forwarded to the inner `<input>`. */
|
|
904
1064
|
name = input(undefined, /* @ts-ignore */
|
|
@@ -922,8 +1082,8 @@ class HlmDateRangeInput extends BrnDateInput {
|
|
|
922
1082
|
}
|
|
923
1083
|
/**
|
|
924
1084
|
* Parses input text into a date range. Return `null` for invalid
|
|
925
|
-
* input
|
|
926
|
-
*
|
|
1085
|
+
* input. Rejected text stays editable and aria-invalid; the committed value
|
|
1086
|
+
* is preserved. Empty text explicitly clears on blur/Enter.
|
|
927
1087
|
*
|
|
928
1088
|
* Defaults to `parseDate` from `HlmDateRangePickerConfig`.
|
|
929
1089
|
*/
|
|
@@ -956,7 +1116,8 @@ class HlmDateRangeInput extends BrnDateInput {
|
|
|
956
1116
|
[placeholder]="placeholder()"
|
|
957
1117
|
[readonly]="readonly()"
|
|
958
1118
|
[disabled]="_disabled()"
|
|
959
|
-
[
|
|
1119
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
1120
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
960
1121
|
[class]="$inputClass()"
|
|
961
1122
|
(click)="_handleClick()"
|
|
962
1123
|
(keydown.arrowDown)="_open()"
|
|
@@ -1010,7 +1171,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
1010
1171
|
[placeholder]="placeholder()"
|
|
1011
1172
|
[readonly]="readonly()"
|
|
1012
1173
|
[disabled]="_disabled()"
|
|
1013
|
-
[
|
|
1174
|
+
[attr.aria-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
1175
|
+
[attr.data-matches-spartan-invalid]="forceInvalid() || inputInvalid() ? 'true' : null"
|
|
1014
1176
|
[class]="$inputClass()"
|
|
1015
1177
|
(click)="_handleClick()"
|
|
1016
1178
|
(keydown.arrowDown)="_open()"
|
|
@@ -1053,6 +1215,11 @@ const HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR = {
|
|
|
1053
1215
|
};
|
|
1054
1216
|
class HlmDateRangePicker {
|
|
1055
1217
|
_config = injectHlmDateRangePickerConfig();
|
|
1218
|
+
_dateAdapter = injectDateAdapter();
|
|
1219
|
+
_commitState = inject(HlmDatePickerCommitState);
|
|
1220
|
+
_calendar = viewChild((BrnCalendarRange), /* @ts-ignore */
|
|
1221
|
+
...(ngDevMode ? [{ debugName: "_calendar" }] : /* istanbul ignore next */ []));
|
|
1222
|
+
_restoringCalendar = false;
|
|
1056
1223
|
popover = viewChild.required(BrnPopover, /* @ts-ignore */
|
|
1057
1224
|
...(ngDevMode ? [{ debugName: "popover" }] : /* istanbul ignore next */ []));
|
|
1058
1225
|
_trigger = contentChild(BrnDatePickerTriggerToken, /* @ts-ignore */
|
|
@@ -1117,50 +1284,85 @@ class HlmDateRangePicker {
|
|
|
1117
1284
|
}
|
|
1118
1285
|
}
|
|
1119
1286
|
_handleStartDayChange(value) {
|
|
1287
|
+
if (this._restoringCalendar)
|
|
1288
|
+
return;
|
|
1289
|
+
if (this._disabled() || (value != null && !isSelectableDate(this._dateAdapter, value, this.min(), this.max()))) {
|
|
1290
|
+
this._restoreCalendar();
|
|
1291
|
+
return;
|
|
1292
|
+
}
|
|
1120
1293
|
this._start.set(value);
|
|
1121
1294
|
}
|
|
1122
1295
|
_handleEndDateChange(value) {
|
|
1123
|
-
this.
|
|
1124
|
-
if (this._disabled())
|
|
1296
|
+
if (this._restoringCalendar)
|
|
1125
1297
|
return;
|
|
1298
|
+
if (this._disabled()) {
|
|
1299
|
+
this._restoreCalendar();
|
|
1300
|
+
return;
|
|
1301
|
+
}
|
|
1302
|
+
if (value == null) {
|
|
1303
|
+
this._end.set(undefined);
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1126
1306
|
const start = this._start();
|
|
1127
|
-
if (start
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1307
|
+
if (start != null) {
|
|
1308
|
+
if (!this.updateDate([start, value])) {
|
|
1309
|
+
this._restoreCalendar();
|
|
1310
|
+
return;
|
|
1311
|
+
}
|
|
1132
1312
|
if (this.autoCloseOnEndSelection()) {
|
|
1133
1313
|
this._popoverState.set('closed');
|
|
1134
1314
|
}
|
|
1135
1315
|
}
|
|
1136
1316
|
}
|
|
1317
|
+
_restoreCalendar() {
|
|
1318
|
+
this._start.set(this._mutableDate()?.[0]);
|
|
1319
|
+
this._end.set(this._mutableDate()?.[1]);
|
|
1320
|
+
this._restoringCalendar = true;
|
|
1321
|
+
try {
|
|
1322
|
+
this._calendar()?.startDate.set(this._start());
|
|
1323
|
+
this._calendar()?.endDate.set(this._end());
|
|
1324
|
+
}
|
|
1325
|
+
finally {
|
|
1326
|
+
this._restoringCalendar = false;
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1137
1329
|
/**
|
|
1138
|
-
* Commit a range
|
|
1139
|
-
*
|
|
1140
|
-
*
|
|
1330
|
+
* Commit a user range (null clears). Both raw/transformed endpoints must
|
|
1331
|
+
* satisfy adapter whole-day bounds; the transformed range must be ordered.
|
|
1332
|
+
* Returns false without changing/emitting the model on rejection or disabled.
|
|
1141
1333
|
*/
|
|
1142
1334
|
updateDate(value) {
|
|
1143
1335
|
if (this._disabled())
|
|
1144
|
-
return;
|
|
1336
|
+
return false;
|
|
1145
1337
|
if (!value) {
|
|
1146
1338
|
this._mutableDate.set(undefined);
|
|
1147
1339
|
this._start.set(undefined);
|
|
1148
1340
|
this._end.set(undefined);
|
|
1341
|
+
this._commitState.changed();
|
|
1149
1342
|
this._onChange?.(null);
|
|
1150
1343
|
this.dateChange.emit(null);
|
|
1151
|
-
return;
|
|
1344
|
+
return true;
|
|
1152
1345
|
}
|
|
1346
|
+
if (!this._isRangeAllowed(value))
|
|
1347
|
+
return false;
|
|
1153
1348
|
const transformedDates = this.transformDates()(value);
|
|
1349
|
+
if (!this._isRangeAllowed(transformedDates) || this._dateAdapter.isAfter(transformedDates[0], transformedDates[1]))
|
|
1350
|
+
return false;
|
|
1154
1351
|
this._mutableDate.set(transformedDates);
|
|
1155
1352
|
this._start.set(transformedDates[0]);
|
|
1156
1353
|
this._end.set(transformedDates[1]);
|
|
1354
|
+
this._commitState.changed();
|
|
1157
1355
|
this._onChange?.(transformedDates);
|
|
1158
1356
|
this.dateChange.emit(transformedDates);
|
|
1357
|
+
return true;
|
|
1358
|
+
}
|
|
1359
|
+
_isRangeAllowed(dates) {
|
|
1360
|
+
return (dates?.length === 2 && dates.every((date) => isSelectableDate(this._dateAdapter, date, this.min(), this.max())));
|
|
1159
1361
|
}
|
|
1160
1362
|
touched() {
|
|
1161
1363
|
this._onTouched?.();
|
|
1162
1364
|
}
|
|
1163
|
-
/**
|
|
1365
|
+
/** Programmatic CVA write: transforms without enforcing user constraints or emitting. Clears rejected text. */
|
|
1164
1366
|
writeValue(value) {
|
|
1165
1367
|
untracked(() => {
|
|
1166
1368
|
if (!value) {
|
|
@@ -1169,6 +1371,7 @@ class HlmDateRangePicker {
|
|
|
1169
1371
|
else {
|
|
1170
1372
|
this._mutableDate.set(this.transformDates()(value));
|
|
1171
1373
|
}
|
|
1374
|
+
this._commitState.changed();
|
|
1172
1375
|
});
|
|
1173
1376
|
}
|
|
1174
1377
|
registerOnChange(fn) {
|
|
@@ -1190,6 +1393,7 @@ class HlmDateRangePicker {
|
|
|
1190
1393
|
this._mutableDate.set(undefined);
|
|
1191
1394
|
this._start.set(undefined);
|
|
1192
1395
|
this._end.set(undefined);
|
|
1396
|
+
this._commitState.changed();
|
|
1193
1397
|
this._onChange?.(null);
|
|
1194
1398
|
this.dateChange.emit(null);
|
|
1195
1399
|
}
|
|
@@ -1202,10 +1406,11 @@ class HlmDateRangePicker {
|
|
|
1202
1406
|
}
|
|
1203
1407
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "22.1.3", ngImport: i0, type: HlmDateRangePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1204
1408
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "22.1.3", type: HlmDateRangePicker, isStandalone: true, selector: "hlm-date-range-picker", inputs: { captionLayout: { classPropertyName: "captionLayout", publicName: "captionLayout", 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 }, date: { classPropertyName: "date", publicName: "date", isSignal: true, isRequired: false, transformFunction: null }, autoCloseOnEndSelection: { classPropertyName: "autoCloseOnEndSelection", publicName: "autoCloseOnEndSelection", isSignal: true, isRequired: false, transformFunction: null }, formatDates: { classPropertyName: "formatDates", publicName: "formatDates", isSignal: true, isRequired: false, transformFunction: null }, transformDates: { classPropertyName: "transformDates", publicName: "transformDates", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { dateChange: "dateChange" }, host: { classAttribute: "block" }, providers: [
|
|
1409
|
+
HlmDatePickerCommitState,
|
|
1205
1410
|
HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR,
|
|
1206
1411
|
provideBrnDatePicker(HlmDateRangePicker),
|
|
1207
1412
|
provideBrnLabelable(HlmDateRangePicker),
|
|
1208
|
-
], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
|
|
1413
|
+
], queries: [{ propertyName: "_trigger", first: true, predicate: BrnDatePickerTriggerToken, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "_calendar", first: true, predicate: (BrnCalendarRange), descendants: true, isSignal: true }, { propertyName: "popover", first: true, predicate: BrnPopover, descendants: true, isSignal: true }], hostDirectives: [{ directive: i1$1.BrnFieldControl }], ngImport: i0, template: `
|
|
1209
1414
|
<hlm-popover sideOffset="5" [state]="_popoverState()" (stateChanged)="_onStateChange($event)">
|
|
1210
1415
|
<ng-content />
|
|
1211
1416
|
|
|
@@ -1233,6 +1438,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
1233
1438
|
selector: 'hlm-date-range-picker',
|
|
1234
1439
|
imports: [HlmPopoverImports, HlmCalendarRange],
|
|
1235
1440
|
providers: [
|
|
1441
|
+
HlmDatePickerCommitState,
|
|
1236
1442
|
HLM_DATE_RANGE_PICKER_VALUE_ACCESSOR,
|
|
1237
1443
|
provideBrnDatePicker(HlmDateRangePicker),
|
|
1238
1444
|
provideBrnLabelable(HlmDateRangePicker),
|
|
@@ -1262,7 +1468,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "22.1.3", ngImpor
|
|
|
1262
1468
|
</hlm-popover>
|
|
1263
1469
|
`,
|
|
1264
1470
|
}]
|
|
1265
|
-
}], propDecorators: { popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", 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 }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnEndSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnEndSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
1471
|
+
}], propDecorators: { _calendar: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnCalendarRange), { isSignal: true }] }], popover: [{ type: i0.ViewChild, args: [i0.forwardRef(() => BrnPopover), { isSignal: true }] }], _trigger: [{ type: i0.ContentChild, args: [i0.forwardRef(() => BrnDatePickerTriggerToken), { isSignal: true }] }], captionLayout: [{ type: i0.Input, args: [{ isSignal: true, alias: "captionLayout", 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 }] }], date: [{ type: i0.Input, args: [{ isSignal: true, alias: "date", required: false }] }], autoCloseOnEndSelection: [{ type: i0.Input, args: [{ isSignal: true, alias: "autoCloseOnEndSelection", required: false }] }], formatDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "formatDates", required: false }] }], transformDates: [{ type: i0.Input, args: [{ isSignal: true, alias: "transformDates", required: false }] }], dateChange: [{ type: i0.Output, args: ["dateChange"] }] } });
|
|
1266
1472
|
|
|
1267
1473
|
const mmYYYY = (date) => {
|
|
1268
1474
|
if (!(date instanceof Date))
|