@ng-modular-forms/core 0.7.9 → 0.8.1

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,70 +1,89 @@
1
1
  import * as i2 from '@angular/forms';
2
- import { NgControl, FormControl, Validators, TouchedChangeEvent, ReactiveFormsModule, FormGroup } from '@angular/forms';
2
+ import { NgControl, Validators, TouchedChangeEvent, ReactiveFormsModule, FormGroup } from '@angular/forms';
3
3
  import * as i0 from '@angular/core';
4
- import { inject, DestroyRef, input, booleanAttribute, signal, computed, Directive, ChangeDetectionStrategy, Component, Injectable } from '@angular/core';
5
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
6
- import { merge, startWith, Subscription } from 'rxjs';
4
+ import { viewChild, input, computed, booleanAttribute, signal, inject, ChangeDetectorRef, DestroyRef, ElementRef, Directive, ChangeDetectionStrategy, Component, effect, Injectable } from '@angular/core';
5
+ import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
6
+ import { merge, startWith, Subject, take, catchError, EMPTY, map, debounceTime, distinctUntilChanged, filter, tap, switchMap, of, Subscription } from 'rxjs';
7
7
  import * as i1 from '@angular/common';
8
- import { CommonModule } from '@angular/common';
8
+ import { CommonModule, AsyncPipe } from '@angular/common';
9
9
 
10
10
  class FormControlBase {
11
- destroyRef = inject(DestroyRef);
12
11
  static nextId = 0;
13
- id = input(`nmf-form-control-${FormControlBase.nextId++}`, { alias: 'id' });
12
+ focusableElement = viewChild('focusable');
13
+ id = input(`nmf-form-control-${FormControlBase.nextId++}`);
14
14
  label = input('');
15
- classList = input([]);
16
15
  loading = input(false);
17
16
  name = input('');
18
17
  placeholder = input('');
18
+ autocompleteAttr = input(null);
19
+ _classList = input('', { alias: 'classList' });
20
+ classList = computed(() => {
21
+ const classList = this._classList();
22
+ if (Array.isArray(classList)) {
23
+ return classList.filter((className) => !!className.trim());
24
+ }
25
+ return classList.split(/\s+/).filter((className) => className.length > 0);
26
+ });
19
27
  _disabledByInput = input(false, {
20
28
  transform: booleanAttribute,
21
29
  alias: 'disabledOverride',
22
30
  });
23
31
  _disabledByCva = signal(false);
32
+ cdr = inject(ChangeDetectorRef);
33
+ destroyRef = inject(DestroyRef);
24
34
  ngControl = inject(NgControl, {
25
- self: true,
26
35
  optional: true,
27
36
  });
28
- standaloneControl = new FormControl(null);
29
- get formControl() {
30
- return (this.ngControl?.control ??
31
- this.standaloneControl);
32
- }
37
+ _focused = signal(false);
38
+ _value = null;
33
39
  disabled = computed(() => this._disabledByInput() || this._disabledByCva());
34
40
  isRequired = signal(this.ngControl?.control?.hasValidator(Validators.required) ?? false);
35
41
  hasErrors = signal(false);
36
42
  onChange = () => { };
37
43
  onTouched = () => { };
44
+ get value() {
45
+ return this._value;
46
+ }
47
+ get control() {
48
+ return this.ngControl?.control;
49
+ }
50
+ get focused() {
51
+ return this._focused();
52
+ }
38
53
  constructor() {
39
54
  if (this.ngControl) {
40
55
  this.ngControl.valueAccessor = this;
41
56
  }
42
57
  }
43
58
  ngOnInit() {
44
- const control = this.ngControl?.control;
59
+ const control = this.control;
45
60
  if (!control)
46
61
  return;
47
62
  merge(control.statusChanges, control.valueChanges)
48
63
  .pipe(startWith(null), takeUntilDestroyed(this.destroyRef))
49
64
  .subscribe(() => {
50
- this.hasErrors.set(control.invalid && control.touched);
51
- this.isRequired.set(control.hasValidator(Validators.required) ?? false);
65
+ this.onControlStateChange();
52
66
  });
53
67
  control.events
54
68
  .pipe(takeUntilDestroyed(this.destroyRef))
55
69
  .subscribe((event) => {
56
70
  if (event instanceof TouchedChangeEvent) {
57
- this.hasErrors.set(control.invalid && control.touched);
71
+ this.onControlStateChange();
58
72
  }
59
73
  });
60
74
  }
61
- writeValue(value) {
62
- const control = this.ngControl?.control;
63
- if (!control)
75
+ onControlStateChange() {
76
+ const control = this.control;
77
+ if (!control) {
64
78
  return;
65
- if (control.value !== value) {
66
- control.setValue(value, { emitEvent: false });
67
79
  }
80
+ this.hasErrors.set(control.invalid && control.touched);
81
+ this.isRequired.set(control.hasValidator(Validators.required) ?? false);
82
+ this.cdr.markForCheck();
83
+ }
84
+ writeValue(value) {
85
+ this._value = value;
86
+ this.cdr.markForCheck();
68
87
  }
69
88
  registerOnChange(fn) {
70
89
  this.onChange = fn;
@@ -75,8 +94,43 @@ class FormControlBase {
75
94
  setDisabledState(isDisabled) {
76
95
  this._disabledByCva.set(isDisabled);
77
96
  }
97
+ focus() {
98
+ const target = this.focusableElement();
99
+ if (!target)
100
+ return;
101
+ // Type guard check for native ElementRef wrapper
102
+ if (target instanceof ElementRef) {
103
+ target.nativeElement.focus();
104
+ }
105
+ // Type guard check for a custom component instance with executable methods
106
+ else if ('focus' in target && typeof target.focus === 'function') {
107
+ target.focus();
108
+ }
109
+ }
110
+ blur() {
111
+ const target = this.focusableElement();
112
+ if (!target)
113
+ return;
114
+ if (target instanceof ElementRef) {
115
+ target.nativeElement.blur();
116
+ }
117
+ else if ('blur' in target && typeof target.blur === 'function') {
118
+ target.blur();
119
+ }
120
+ }
121
+ onFocusIn() {
122
+ if (this.focused) {
123
+ return;
124
+ }
125
+ this._focused.set(true);
126
+ }
127
+ onFocusOut() {
128
+ //this.control?.markAsTouched();
129
+ this._focused.set(false);
130
+ this.onTouched();
131
+ }
78
132
  errorMessage() {
79
- const control = this.ngControl?.control;
133
+ const control = this.control;
80
134
  if (control == null || !control.errors || !control.touched)
81
135
  return null;
82
136
  const firstKey = Object.keys(control.errors)[0];
@@ -105,10 +159,10 @@ class FormControlBase {
105
159
  return 'Invalid value';
106
160
  }
107
161
  }
108
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormControlBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
109
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.2.21", type: FormControlBase, isStandalone: true, inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, classList: { classPropertyName: "classList", publicName: "classList", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, _disabledByInput: { classPropertyName: "_disabledByInput", publicName: "disabledOverride", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
162
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormControlBase, deps: [], target: i0.ɵɵFactoryTarget.Directive });
163
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.2.0", version: "19.2.25", type: FormControlBase, isStandalone: true, inputs: { id: { classPropertyName: "id", publicName: "id", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, name: { classPropertyName: "name", publicName: "name", isSignal: true, isRequired: false, transformFunction: null }, placeholder: { classPropertyName: "placeholder", publicName: "placeholder", isSignal: true, isRequired: false, transformFunction: null }, autocompleteAttr: { classPropertyName: "autocompleteAttr", publicName: "autocompleteAttr", isSignal: true, isRequired: false, transformFunction: null }, _classList: { classPropertyName: "_classList", publicName: "classList", isSignal: true, isRequired: false, transformFunction: null }, _disabledByInput: { classPropertyName: "_disabledByInput", publicName: "disabledOverride", isSignal: true, isRequired: false, transformFunction: null } }, viewQueries: [{ propertyName: "focusableElement", first: true, predicate: ["focusable"], descendants: true, isSignal: true }], ngImport: i0 });
110
164
  }
111
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormControlBase, decorators: [{
165
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormControlBase, decorators: [{
112
166
  type: Directive
113
167
  }], ctorParameters: () => [] });
114
168
 
@@ -246,6 +300,125 @@ class CurrencyBehavior {
246
300
  }
247
301
  }
248
302
 
303
+ class LookupBehavior {
304
+ _status = signal('default');
305
+ _options = signal([]);
306
+ _selectedOption = signal(null);
307
+ status = this._status.asReadonly();
308
+ options = this._options.asReadonly();
309
+ selectedOption = this._selectedOption.asReadonly();
310
+ /*
311
+ * Emits when the options have been updated. Ensures Material autocomplete updates its
312
+ */
313
+ optionsUpdated$ = new Subject();
314
+ filteredOptions;
315
+ bOptions;
316
+ constructor(bOptions) {
317
+ this.bOptions = bOptions;
318
+ }
319
+ setSelectedOption(value) {
320
+ this._selectedOption.set(value);
321
+ }
322
+ selectOption(event, option) {
323
+ event?.stopPropagation();
324
+ const compare = this.bOptions.resolvers.compare() ?? undefined;
325
+ const selected = this.options().find((o) => compare ? compare(o.value, option.value) : o.value === option.value);
326
+ if (!selected) {
327
+ return;
328
+ }
329
+ this.setSelectedOption(selected);
330
+ }
331
+ clearSelectedOption() {
332
+ this.setSelectedOption(null);
333
+ this.optionsUpdated$.next();
334
+ }
335
+ selectedMatchedOption(value) {
336
+ const { destroyRef, resolvers } = this.bOptions;
337
+ const compare = resolvers.compare() ?? undefined;
338
+ const label = resolvers.label() ?? undefined;
339
+ const labelAsync = resolvers.labelAsync() ?? undefined;
340
+ const match = this._options().find((o) => compare ? compare(o.value, value) : o.value === value) ?? null;
341
+ if (match) {
342
+ this._selectedOption.set(match);
343
+ return;
344
+ }
345
+ if (value === null) {
346
+ this._selectedOption.set(null);
347
+ return;
348
+ }
349
+ if (labelAsync) {
350
+ this._status.set('loading');
351
+ labelAsync(value)
352
+ .pipe(take(1), catchError(() => {
353
+ this._status.set('error');
354
+ return EMPTY;
355
+ }), takeUntilDestroyed(destroyRef))
356
+ .subscribe((label) => {
357
+ this._selectedOption.set({
358
+ value,
359
+ label,
360
+ });
361
+ this._status.set('default');
362
+ });
363
+ return;
364
+ }
365
+ if (label) {
366
+ this._selectedOption.set({
367
+ value: value,
368
+ label: label(value),
369
+ });
370
+ return;
371
+ }
372
+ }
373
+ updateOptions(results, status) {
374
+ this._status.set(status ?? 'default');
375
+ this._options.set(results);
376
+ this.optionsUpdated$.next();
377
+ }
378
+ filterOptions(name, results) {
379
+ const filterValue = name.toLowerCase();
380
+ return results.filter((option) => option.label.toLowerCase().includes(filterValue) ||
381
+ String(option.value).includes(filterValue));
382
+ }
383
+ setupFilteredOptions(source, searchQuery) {
384
+ this.filteredOptions = merge(source, this.optionsUpdated$).pipe(startWith(''), map(() => {
385
+ const options = this.options();
386
+ let value = searchQuery;
387
+ if (typeof searchQuery === 'function') {
388
+ value = searchQuery();
389
+ }
390
+ if (typeof value !== 'string') {
391
+ return this.options().slice();
392
+ }
393
+ return value ? this.filterOptions(value, options) : options.slice();
394
+ }));
395
+ }
396
+ setupOptionsProvider(source, debounceDelay, searchThreshold) {
397
+ const { destroyRef, resolvers } = this.bOptions;
398
+ const search = resolvers.search() ?? undefined;
399
+ if (!search) {
400
+ return;
401
+ }
402
+ source.pipe(takeUntilDestroyed(destroyRef)).subscribe((value) => {
403
+ if (!value || value.length < searchThreshold) {
404
+ this.updateOptions([]);
405
+ }
406
+ });
407
+ source
408
+ .pipe(debounceTime(debounceDelay), distinctUntilChanged((a, b) => a === b), filter(() => this.selectedOption() == null), filter((q) => typeof q === 'string' && q.length >= searchThreshold), tap(() => this.updateOptions([], 'loading')), switchMap((query) => search(query).pipe(catchError(() => {
409
+ this._status.set('error');
410
+ return of(null);
411
+ }))), takeUntilDestroyed(destroyRef))
412
+ .subscribe((response) => {
413
+ if (!response) {
414
+ return;
415
+ }
416
+ const status = response.length ? 'default' : 'empty';
417
+ this.updateOptions(response, status);
418
+ });
419
+ }
420
+ }
421
+
249
422
  class TextBehavior {
250
423
  _showPassword = signal(false);
251
424
  showPassword = this._showPassword.asReadonly();
@@ -259,9 +432,11 @@ class FormFieldComponent {
259
432
  label = input();
260
433
  isRequired = input();
261
434
  loading = input();
435
+ hint = input();
262
436
  errorMessage = input();
263
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
264
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: FormFieldComponent, isStandalone: true, selector: "nmf-form-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isRequired: { classPropertyName: "isRequired", publicName: "isRequired", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
437
+ hasErrors = computed(() => this.errorMessage() != null);
438
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormFieldComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
439
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: FormFieldComponent, isStandalone: true, selector: "nmf-form-field", inputs: { label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null }, isRequired: { classPropertyName: "isRequired", publicName: "isRequired", isSignal: true, isRequired: false, transformFunction: null }, loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, hint: { classPropertyName: "hint", publicName: "hint", isSignal: true, isRequired: false, transformFunction: null }, errorMessage: { classPropertyName: "errorMessage", publicName: "errorMessage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
265
440
  <div class="nmf-field" [class.loading]="loading()">
266
441
  @if (label()) {
267
442
  <label class="nmf-label">
@@ -280,13 +455,19 @@ class FormFieldComponent {
280
455
  </div>
281
456
  }
282
457
 
283
- <p class="nmf-error">
458
+ @if (hint()) {
459
+ <p class="nmf-hint">
460
+ {{ hint() }}
461
+ </p>
462
+ }
463
+
464
+ <p class="nmf-hint" [class.error]="hasErrors()">
284
465
  {{ errorMessage() }}
285
466
  </p>
286
467
  </div>
287
468
  `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: ReactiveFormsModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
288
469
  }
289
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormFieldComponent, decorators: [{
470
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormFieldComponent, decorators: [{
290
471
  type: Component,
291
472
  args: [{
292
473
  selector: 'nmf-form-field',
@@ -312,7 +493,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
312
493
  </div>
313
494
  }
314
495
 
315
- <p class="nmf-error">
496
+ @if (hint()) {
497
+ <p class="nmf-hint">
498
+ {{ hint() }}
499
+ </p>
500
+ }
501
+
502
+ <p class="nmf-hint" [class.error]="hasErrors()">
316
503
  {{ errorMessage() }}
317
504
  </p>
318
505
  </div>
@@ -347,8 +534,8 @@ class InputCurrencyComponent extends FormControlBase {
347
534
  const valid = parsedValue != null && parsedValue >= 0;
348
535
  return valid ? 'inherit' : '#dc6262';
349
536
  });
350
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputCurrencyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
351
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputCurrencyComponent, isStandalone: true, selector: "nmf-currency", usesInheritance: true, ngImport: i0, template: `
537
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputCurrencyComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
538
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: InputCurrencyComponent, isStandalone: true, selector: "nmf-currency", usesInheritance: true, ngImport: i0, template: `
352
539
  <nmf-form-field
353
540
  [label]="label()"
354
541
  [isRequired]="isRequired()"
@@ -368,8 +555,8 @@ class InputCurrencyComponent extends FormControlBase {
368
555
  }
369
556
 
370
557
  <input
558
+ #focusable
371
559
  type="text"
372
- autocomplete="off"
373
560
  class="nmf-input"
374
561
  [ngClass]="classList()"
375
562
  [class.error]="hasErrors()"
@@ -382,15 +569,16 @@ class InputCurrencyComponent extends FormControlBase {
382
569
  [disabled]="disabled()"
383
570
  [required]="isRequired()"
384
571
  [placeholder]="placeholder()"
572
+ [autocomplete]="autocompleteAttr()"
385
573
  (blur)="onTouched()"
386
574
  (input)="onInput($event)"
387
575
  (keydown)="handleKeyDown($event)"
388
576
  />
389
577
  </div>
390
578
  </nmf-form-field>
391
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
579
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
392
580
  }
393
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputCurrencyComponent, decorators: [{
581
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputCurrencyComponent, decorators: [{
394
582
  type: Component,
395
583
  args: [{
396
584
  selector: 'nmf-currency',
@@ -417,8 +605,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
417
605
  }
418
606
 
419
607
  <input
608
+ #focusable
420
609
  type="text"
421
- autocomplete="off"
422
610
  class="nmf-input"
423
611
  [ngClass]="classList()"
424
612
  [class.error]="hasErrors()"
@@ -431,6 +619,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
431
619
  [disabled]="disabled()"
432
620
  [required]="isRequired()"
433
621
  [placeholder]="placeholder()"
622
+ [autocomplete]="autocompleteAttr()"
434
623
  (blur)="onTouched()"
435
624
  (input)="onInput($event)"
436
625
  (keydown)="handleKeyDown($event)"
@@ -472,8 +661,8 @@ class InputDatepickerComponent extends FormControlBase {
472
661
  this.displayValue.set(this.formatDate(parsed) ?? '');
473
662
  this.onChange(parsed);
474
663
  }
475
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
476
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: InputDatepickerComponent, isStandalone: true, selector: "nmf-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
664
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputDatepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
665
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.25", type: InputDatepickerComponent, isStandalone: true, selector: "nmf-datepicker", inputs: { minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
477
666
  <nmf-form-field
478
667
  [label]="label()"
479
668
  [isRequired]="isRequired()"
@@ -481,6 +670,7 @@ class InputDatepickerComponent extends FormControlBase {
481
670
  [errorMessage]="errorMessage()"
482
671
  >
483
672
  <input
673
+ #focusable
484
674
  type="date"
485
675
  class="nmf-input"
486
676
  [ngClass]="classList()"
@@ -494,13 +684,14 @@ class InputDatepickerComponent extends FormControlBase {
494
684
  [disabled]="disabled()"
495
685
  [required]="isRequired()"
496
686
  [placeholder]="placeholder()"
687
+ [autocomplete]="autocompleteAttr()"
497
688
  (blur)="onTouched()"
498
689
  (input)="onInput($event)"
499
690
  />
500
691
  </nmf-form-field>
501
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
692
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
502
693
  }
503
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputDatepickerComponent, decorators: [{
694
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputDatepickerComponent, decorators: [{
504
695
  type: Component,
505
696
  args: [{
506
697
  selector: 'nmf-datepicker',
@@ -515,6 +706,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
515
706
  [errorMessage]="errorMessage()"
516
707
  >
517
708
  <input
709
+ #focusable
518
710
  type="date"
519
711
  class="nmf-input"
520
712
  [ngClass]="classList()"
@@ -528,6 +720,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
528
720
  [disabled]="disabled()"
529
721
  [required]="isRequired()"
530
722
  [placeholder]="placeholder()"
723
+ [autocomplete]="autocompleteAttr()"
531
724
  (blur)="onTouched()"
532
725
  (input)="onInput($event)"
533
726
  />
@@ -536,6 +729,326 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
536
729
  }]
537
730
  }] });
538
731
 
732
+ class InputLookupComponent extends FormControlBase {
733
+ autocompleteAttr = input('off');
734
+ /*
735
+ * Static options to display in the dropdown. This is for synchronous sources.
736
+ */
737
+ optionsSource = input([]);
738
+ /*
739
+ * Must return a cancellable observable. This is for asynchronous sources (API calls, etc).
740
+ */
741
+ optionsProvider = input();
742
+ /*
743
+ * When using a synchronous options source, or an asynchronous provider that returns an object where the shape is known,
744
+ * this function is used to determine the display value.
745
+ */
746
+ displayWith = input();
747
+ /*
748
+ * Used to determine the display value asynchronously when using primitive types for form values
749
+ * eg: countryCode instead of Country itself.
750
+ *
751
+ * If not provided, the raw value will be used. Only needed for patching/hydrating the form.
752
+ */
753
+ displayProvider = input();
754
+ /*
755
+ * Used to compare options during selection if object equality is not sufficient.
756
+ */
757
+ compareWith = input();
758
+ /*
759
+ * The provided hint will be displayed when asynchronous lookup is empty.
760
+ */
761
+ emptyOptionsLabel = input('No results found');
762
+ /*
763
+ * Search will be debounced by this many milliseconds.
764
+ */
765
+ debounceTime = input(500);
766
+ /*
767
+ * Search will not be triggered until the user has typed at least this many characters.
768
+ */
769
+ searchThreshold = input(2);
770
+ _activeIndex = signal(-1);
771
+ activeIndex = this._activeIndex.asReadonly();
772
+ _searchQuery = signal('');
773
+ _isInteractingWithOptions = signal(false);
774
+ _searchQuery$ = toObservable(this._searchQuery);
775
+ isOpen = signal(false);
776
+ openUpwards = signal(false);
777
+ displayLabel = computed(() => {
778
+ const selected = this.behavior.selectedOption();
779
+ if (selected) {
780
+ return selected.label;
781
+ }
782
+ return this._searchQuery();
783
+ });
784
+ inputElement = inject((ElementRef));
785
+ behavior;
786
+ constructor() {
787
+ super();
788
+ this.behavior = new LookupBehavior({
789
+ destroyRef: this.destroyRef,
790
+ resolvers: {
791
+ compare: this.compareWith,
792
+ label: this.displayWith,
793
+ labelAsync: this.displayProvider,
794
+ search: this.optionsProvider,
795
+ },
796
+ });
797
+ effect(() => {
798
+ const currentOptions = this.optionsSource() ?? [];
799
+ this.updateOptions(currentOptions);
800
+ });
801
+ effect(() => {
802
+ const selectedOption = this.behavior.selectedOption();
803
+ this.onChange(selectedOption?.value ?? null);
804
+ });
805
+ }
806
+ ngOnInit() {
807
+ super.ngOnInit();
808
+ this.behavior.setupFilteredOptions(this._searchQuery$, this._searchQuery);
809
+ this.behavior.setupOptionsProvider(this._searchQuery$, 500, 2);
810
+ }
811
+ writeValue(value) {
812
+ super.writeValue(value);
813
+ this.behavior.selectedMatchedOption(value);
814
+ }
815
+ onFocusOut() {
816
+ super.onFocusOut();
817
+ if (this._isInteractingWithOptions()) {
818
+ return;
819
+ }
820
+ this.isOpen.set(false);
821
+ }
822
+ onFocusIn() {
823
+ super.onFocusIn();
824
+ if (!this.behavior.selectedOption()) {
825
+ this.calculateDropdownPosition();
826
+ this.isOpen.set(true);
827
+ }
828
+ }
829
+ ngOnDestroy() {
830
+ this.behavior.optionsUpdated$.complete();
831
+ }
832
+ onInput(event) {
833
+ this._searchQuery.set(event.target.value);
834
+ }
835
+ selectOption(event, option) {
836
+ this.behavior.selectOption(event, option);
837
+ this._isInteractingWithOptions.set(false);
838
+ this.isOpen.set(false);
839
+ }
840
+ resetActiveIndex() {
841
+ this._activeIndex.set(-1);
842
+ }
843
+ setOptionsInteraction(state) {
844
+ this._isInteractingWithOptions.set(state);
845
+ }
846
+ updateOptions(results, status) {
847
+ this.behavior.updateOptions(results, status);
848
+ this.resetActiveIndex();
849
+ }
850
+ clearSelectedOption() {
851
+ this._searchQuery.set('');
852
+ this.behavior.clearSelectedOption();
853
+ this.focus();
854
+ }
855
+ onKeyDown(event, currentOptions) {
856
+ if (!this.isOpen() || !currentOptions || currentOptions.length === 0) {
857
+ if (event.key === 'ArrowDown') {
858
+ this.calculateDropdownPosition();
859
+ this.isOpen.set(true);
860
+ event.preventDefault();
861
+ }
862
+ return;
863
+ }
864
+ switch (event.key) {
865
+ case 'ArrowDown':
866
+ event.preventDefault();
867
+ this._activeIndex.update((prev) => prev + 1 >= currentOptions.length ? 0 : prev + 1);
868
+ break;
869
+ case 'ArrowUp':
870
+ event.preventDefault();
871
+ this._activeIndex.update((prev) => prev - 1 < 0 ? currentOptions.length - 1 : prev - 1);
872
+ break;
873
+ case 'Enter':
874
+ event.preventDefault();
875
+ if (this._activeIndex() >= 0 &&
876
+ this._activeIndex() < currentOptions.length) {
877
+ this.selectOption(event, currentOptions[this._activeIndex()]);
878
+ }
879
+ break;
880
+ case 'Escape':
881
+ event.preventDefault();
882
+ this.isOpen.set(false);
883
+ this.resetActiveIndex();
884
+ break;
885
+ case 'Backspace':
886
+ case 'Delete':
887
+ if (this.behavior.selectedOption() !== null) {
888
+ event.preventDefault();
889
+ this.clearSelectedOption();
890
+ }
891
+ break;
892
+ }
893
+ }
894
+ calculateDropdownPosition() {
895
+ const rect = this.inputElement.nativeElement.getBoundingClientRect();
896
+ const spaceBelow = window.innerHeight - rect.bottom;
897
+ const spaceAbove = rect.top;
898
+ this.openUpwards.set(spaceBelow < 225 && spaceAbove > spaceBelow);
899
+ }
900
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputLookupComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
901
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: InputLookupComponent, isStandalone: true, selector: "nmf-lookup", inputs: { autocompleteAttr: { classPropertyName: "autocompleteAttr", publicName: "autocompleteAttr", isSignal: true, isRequired: false, transformFunction: null }, optionsSource: { classPropertyName: "optionsSource", publicName: "optionsSource", isSignal: true, isRequired: false, transformFunction: null }, optionsProvider: { classPropertyName: "optionsProvider", publicName: "optionsProvider", isSignal: true, isRequired: false, transformFunction: null }, displayWith: { classPropertyName: "displayWith", publicName: "displayWith", isSignal: true, isRequired: false, transformFunction: null }, displayProvider: { classPropertyName: "displayProvider", publicName: "displayProvider", isSignal: true, isRequired: false, transformFunction: null }, compareWith: { classPropertyName: "compareWith", publicName: "compareWith", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionsLabel: { classPropertyName: "emptyOptionsLabel", publicName: "emptyOptionsLabel", isSignal: true, isRequired: false, transformFunction: null }, debounceTime: { classPropertyName: "debounceTime", publicName: "debounceTime", isSignal: true, isRequired: false, transformFunction: null }, searchThreshold: { classPropertyName: "searchThreshold", publicName: "searchThreshold", isSignal: true, isRequired: false, transformFunction: null } }, exportAs: ["nmfLookup"], usesInheritance: true, ngImport: i0, template: `
902
+ <nmf-form-field
903
+ [label]="label()"
904
+ [hint]="behavior.status() === 'empty' ? emptyOptionsLabel() : null"
905
+ [isRequired]="isRequired()"
906
+ [loading]="behavior.status() === 'loading' || loading()"
907
+ [errorMessage]="errorMessage()"
908
+ >
909
+ <div class="nmf-input-wrapper" [style.position]="'relative'">
910
+ @if ({ options: behavior.filteredOptions | async }; as stream) {
911
+ <input
912
+ #focusable
913
+ type="text"
914
+ class="nmf-input"
915
+ [attr.list]="id + '-options'"
916
+ [ngClass]="classList()"
917
+ [class.error]="hasErrors()"
918
+ [class.disabled]="disabled()"
919
+ [style.cursor]="
920
+ behavior.selectedOption() != null ? 'not-allowed' : 'text'
921
+ "
922
+ [id]="id()"
923
+ [name]="name()"
924
+ [value]="displayLabel()"
925
+ [disabled]="disabled()"
926
+ [required]="isRequired()"
927
+ [readonly]="behavior.selectedOption() != null"
928
+ [placeholder]="placeholder()"
929
+ [autocomplete]="autocompleteAttr()"
930
+ (blur)="onFocusOut()"
931
+ (focus)="onFocusIn()"
932
+ (input)="onInput($event)"
933
+ (keydown)="onKeyDown($event, stream.options)"
934
+ />
935
+
936
+ @if (isOpen() && stream.options && stream.options.length > 0) {
937
+ <ul
938
+ class="nmf-options-list"
939
+ [class.upward]="openUpwards()"
940
+ (pointerdown)="setOptionsInteraction(true)"
941
+ (pointerup)="setOptionsInteraction(false)"
942
+ >
943
+ @for (option of stream.options; track option; let i = $index) {
944
+ <li
945
+ [class.selected]="behavior.selectedOption() == option"
946
+ [class.active]="activeIndex() === i"
947
+ (click)="selectOption($event, option)"
948
+ >
949
+ {{
950
+ displayWith() ? displayWith()!(option.value) : option.label
951
+ }}
952
+ </li>
953
+ }
954
+ </ul>
955
+ }
956
+
957
+ @if (behavior.selectedOption() && !disabled()) {
958
+ <button
959
+ class="nmf-clear-button"
960
+ type="button"
961
+ aria-label="Clear selection"
962
+ (click)="clearSelectedOption()"
963
+ >
964
+ X
965
+ </button>
966
+ }
967
+ }
968
+ </div>
969
+ </nmf-form-field>
970
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
971
+ }
972
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputLookupComponent, decorators: [{
973
+ type: Component,
974
+ args: [{
975
+ selector: 'nmf-lookup',
976
+ exportAs: 'nmfLookup',
977
+ imports: [CommonModule, ReactiveFormsModule, FormFieldComponent, AsyncPipe],
978
+ changeDetection: ChangeDetectionStrategy.OnPush,
979
+ template: `
980
+ <nmf-form-field
981
+ [label]="label()"
982
+ [hint]="behavior.status() === 'empty' ? emptyOptionsLabel() : null"
983
+ [isRequired]="isRequired()"
984
+ [loading]="behavior.status() === 'loading' || loading()"
985
+ [errorMessage]="errorMessage()"
986
+ >
987
+ <div class="nmf-input-wrapper" [style.position]="'relative'">
988
+ @if ({ options: behavior.filteredOptions | async }; as stream) {
989
+ <input
990
+ #focusable
991
+ type="text"
992
+ class="nmf-input"
993
+ [attr.list]="id + '-options'"
994
+ [ngClass]="classList()"
995
+ [class.error]="hasErrors()"
996
+ [class.disabled]="disabled()"
997
+ [style.cursor]="
998
+ behavior.selectedOption() != null ? 'not-allowed' : 'text'
999
+ "
1000
+ [id]="id()"
1001
+ [name]="name()"
1002
+ [value]="displayLabel()"
1003
+ [disabled]="disabled()"
1004
+ [required]="isRequired()"
1005
+ [readonly]="behavior.selectedOption() != null"
1006
+ [placeholder]="placeholder()"
1007
+ [autocomplete]="autocompleteAttr()"
1008
+ (blur)="onFocusOut()"
1009
+ (focus)="onFocusIn()"
1010
+ (input)="onInput($event)"
1011
+ (keydown)="onKeyDown($event, stream.options)"
1012
+ />
1013
+
1014
+ @if (isOpen() && stream.options && stream.options.length > 0) {
1015
+ <ul
1016
+ class="nmf-options-list"
1017
+ [class.upward]="openUpwards()"
1018
+ (pointerdown)="setOptionsInteraction(true)"
1019
+ (pointerup)="setOptionsInteraction(false)"
1020
+ >
1021
+ @for (option of stream.options; track option; let i = $index) {
1022
+ <li
1023
+ [class.selected]="behavior.selectedOption() == option"
1024
+ [class.active]="activeIndex() === i"
1025
+ (click)="selectOption($event, option)"
1026
+ >
1027
+ {{
1028
+ displayWith() ? displayWith()!(option.value) : option.label
1029
+ }}
1030
+ </li>
1031
+ }
1032
+ </ul>
1033
+ }
1034
+
1035
+ @if (behavior.selectedOption() && !disabled()) {
1036
+ <button
1037
+ class="nmf-clear-button"
1038
+ type="button"
1039
+ aria-label="Clear selection"
1040
+ (click)="clearSelectedOption()"
1041
+ >
1042
+ X
1043
+ </button>
1044
+ }
1045
+ }
1046
+ </div>
1047
+ </nmf-form-field>
1048
+ `,
1049
+ }]
1050
+ }], ctorParameters: () => [] });
1051
+
539
1052
  class InputNumberComponent extends FormControlBase {
540
1053
  formatValue = input(false);
541
1054
  displayValue = signal('');
@@ -564,8 +1077,8 @@ class InputNumberComponent extends FormControlBase {
564
1077
  this.displayValue.set(value != null ? String(value) : '');
565
1078
  }
566
1079
  }
567
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputNumberComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
568
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: InputNumberComponent, isStandalone: true, selector: "nmf-number", inputs: { formatValue: { classPropertyName: "formatValue", publicName: "formatValue", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1080
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputNumberComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1081
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.25", type: InputNumberComponent, isStandalone: true, selector: "nmf-number", inputs: { formatValue: { classPropertyName: "formatValue", publicName: "formatValue", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
569
1082
  <nmf-form-field
570
1083
  [label]="label()"
571
1084
  [isRequired]="isRequired()"
@@ -573,7 +1086,7 @@ class InputNumberComponent extends FormControlBase {
573
1086
  [errorMessage]="errorMessage()"
574
1087
  >
575
1088
  <input
576
- autocomplete="off"
1089
+ #focusable
577
1090
  class="nmf-input"
578
1091
  [ngClass]="classList()"
579
1092
  [class.error]="hasErrors()"
@@ -585,14 +1098,15 @@ class InputNumberComponent extends FormControlBase {
585
1098
  [disabled]="disabled()"
586
1099
  [required]="isRequired()"
587
1100
  [placeholder]="placeholder()"
1101
+ [autocomplete]="autocompleteAttr()"
588
1102
  (blur)="onTouched()"
589
1103
  (input)="onInput($event)"
590
1104
  (keydown)="handleKeyDown($event)"
591
1105
  />
592
1106
  </nmf-form-field>
593
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1107
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
594
1108
  }
595
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputNumberComponent, decorators: [{
1109
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputNumberComponent, decorators: [{
596
1110
  type: Component,
597
1111
  args: [{
598
1112
  selector: 'nmf-number',
@@ -607,7 +1121,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
607
1121
  [errorMessage]="errorMessage()"
608
1122
  >
609
1123
  <input
610
- autocomplete="off"
1124
+ #focusable
611
1125
  class="nmf-input"
612
1126
  [ngClass]="classList()"
613
1127
  [class.error]="hasErrors()"
@@ -619,6 +1133,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
619
1133
  [disabled]="disabled()"
620
1134
  [required]="isRequired()"
621
1135
  [placeholder]="placeholder()"
1136
+ [autocomplete]="autocompleteAttr()"
622
1137
  (blur)="onTouched()"
623
1138
  (input)="onInput($event)"
624
1139
  (keydown)="handleKeyDown($event)"
@@ -631,9 +1146,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
631
1146
  class InputSelectComponent extends FormControlBase {
632
1147
  options = input([]);
633
1148
  emptyOptionLabel = input('Select an option');
634
- clearOptionLabel = input('Clear selection');
635
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
636
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputSelectComponent, isStandalone: true, selector: "nmf-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionLabel: { classPropertyName: "emptyOptionLabel", publicName: "emptyOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, clearOptionLabel: { classPropertyName: "clearOptionLabel", publicName: "clearOptionLabel", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1149
+ allowEmptyOptionSelection = input(false);
1150
+ handleChange(event) {
1151
+ if (this._disabledByCva())
1152
+ return;
1153
+ const input = event.target;
1154
+ this.onChange(input.value || null);
1155
+ }
1156
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1157
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: InputSelectComponent, isStandalone: true, selector: "nmf-select", inputs: { options: { classPropertyName: "options", publicName: "options", isSignal: true, isRequired: false, transformFunction: null }, emptyOptionLabel: { classPropertyName: "emptyOptionLabel", publicName: "emptyOptionLabel", isSignal: true, isRequired: false, transformFunction: null }, allowEmptyOptionSelection: { classPropertyName: "allowEmptyOptionSelection", publicName: "allowEmptyOptionSelection", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
637
1158
  <nmf-form-field
638
1159
  [label]="label()"
639
1160
  [isRequired]="isRequired()"
@@ -642,38 +1163,36 @@ class InputSelectComponent extends FormControlBase {
642
1163
  >
643
1164
  <div class="select-wrapper" [class.disabled]="disabled()">
644
1165
  <select
1166
+ #focusable
645
1167
  class="nmf-input"
646
1168
  [ngClass]="classList()"
647
1169
  [class.error]="hasErrors()"
648
1170
  [class.disabled]="disabled()"
1171
+ [id]="id()"
1172
+ [value]="value ?? ''"
1173
+ [disabled]="disabled()"
649
1174
  [required]="isRequired()"
650
- [formControl]="formControl"
1175
+ [autocomplete]="autocompleteAttr()"
651
1176
  (blur)="onTouched()"
1177
+ (change)="handleChange($event)"
652
1178
  >
653
1179
  <!-- Empty option -->
654
- <option [ngValue]="null" disabled>
1180
+ <option [value]="''" [disabled]="!allowEmptyOptionSelection()">
655
1181
  {{ emptyOptionLabel() }}
656
1182
  </option>
657
1183
 
658
1184
  <!-- Options -->
659
- @for (option of options(); track option.key) {
660
- <option [ngValue]="option.key" [disabled]="option.disabled">
1185
+ @for (option of options(); track option.value) {
1186
+ <option [value]="option.value" [disabled]="option.disabled">
661
1187
  {{ option.label }}
662
1188
  </option>
663
1189
  }
664
-
665
- <!-- Clear option -->
666
- @if (clearOptionLabel()) {
667
- <option [ngValue]="null">
668
- {{ clearOptionLabel() }}
669
- </option>
670
- }
671
1190
  </select>
672
1191
  </div>
673
1192
  </nmf-form-field>
674
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1193
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i2.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
675
1194
  }
676
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputSelectComponent, decorators: [{
1195
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputSelectComponent, decorators: [{
677
1196
  type: Component,
678
1197
  args: [{
679
1198
  selector: 'nmf-select',
@@ -689,32 +1208,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
689
1208
  >
690
1209
  <div class="select-wrapper" [class.disabled]="disabled()">
691
1210
  <select
1211
+ #focusable
692
1212
  class="nmf-input"
693
1213
  [ngClass]="classList()"
694
1214
  [class.error]="hasErrors()"
695
1215
  [class.disabled]="disabled()"
1216
+ [id]="id()"
1217
+ [value]="value ?? ''"
1218
+ [disabled]="disabled()"
696
1219
  [required]="isRequired()"
697
- [formControl]="formControl"
1220
+ [autocomplete]="autocompleteAttr()"
698
1221
  (blur)="onTouched()"
1222
+ (change)="handleChange($event)"
699
1223
  >
700
1224
  <!-- Empty option -->
701
- <option [ngValue]="null" disabled>
1225
+ <option [value]="''" [disabled]="!allowEmptyOptionSelection()">
702
1226
  {{ emptyOptionLabel() }}
703
1227
  </option>
704
1228
 
705
1229
  <!-- Options -->
706
- @for (option of options(); track option.key) {
707
- <option [ngValue]="option.key" [disabled]="option.disabled">
1230
+ @for (option of options(); track option.value) {
1231
+ <option [value]="option.value" [disabled]="option.disabled">
708
1232
  {{ option.label }}
709
1233
  </option>
710
1234
  }
711
-
712
- <!-- Clear option -->
713
- @if (clearOptionLabel()) {
714
- <option [ngValue]="null">
715
- {{ clearOptionLabel() }}
716
- </option>
717
- }
718
1235
  </select>
719
1236
  </div>
720
1237
  </nmf-form-field>
@@ -728,8 +1245,14 @@ class InputTextComponent extends FormControlBase {
728
1245
  computedType = computed(() => this.behavior.showPassword() && this.type() === 'password'
729
1246
  ? 'text'
730
1247
  : this.type());
731
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
732
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.21", type: InputTextComponent, isStandalone: true, selector: "nmf-text", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1248
+ onInput(event) {
1249
+ if (this._disabledByInput())
1250
+ return;
1251
+ const input = event.target;
1252
+ this.onChange(input.value);
1253
+ }
1254
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTextComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1255
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.25", type: InputTextComponent, isStandalone: true, selector: "nmf-text", inputs: { type: { classPropertyName: "type", publicName: "type", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
733
1256
  <nmf-form-field
734
1257
  [label]="label()"
735
1258
  [isRequired]="isRequired()"
@@ -738,6 +1261,7 @@ class InputTextComponent extends FormControlBase {
738
1261
  >
739
1262
  <div class="nmf-input-wrapper">
740
1263
  <input
1264
+ #focusable
741
1265
  class="nmf-input"
742
1266
  [ngClass]="classList()"
743
1267
  [class.error]="hasErrors()"
@@ -745,10 +1269,13 @@ class InputTextComponent extends FormControlBase {
745
1269
  [id]="id()"
746
1270
  [name]="name()"
747
1271
  [type]="computedType()"
1272
+ [value]="value"
1273
+ [disabled]="disabled()"
748
1274
  [required]="isRequired()"
749
1275
  [placeholder]="placeholder()"
750
- [formControl]="formControl"
1276
+ [autocomplete]="autocompleteAttr()"
751
1277
  (blur)="onTouched()"
1278
+ (input)="onInput($event)"
752
1279
  />
753
1280
 
754
1281
  @if (type() === 'password' && !loading() && !disabled()) {
@@ -802,9 +1329,9 @@ class InputTextComponent extends FormControlBase {
802
1329
  />
803
1330
  </svg>
804
1331
  </ng-template>
805
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1332
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
806
1333
  }
807
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextComponent, decorators: [{
1334
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTextComponent, decorators: [{
808
1335
  type: Component,
809
1336
  args: [{
810
1337
  selector: 'nmf-text',
@@ -820,6 +1347,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
820
1347
  >
821
1348
  <div class="nmf-input-wrapper">
822
1349
  <input
1350
+ #focusable
823
1351
  class="nmf-input"
824
1352
  [ngClass]="classList()"
825
1353
  [class.error]="hasErrors()"
@@ -827,10 +1355,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
827
1355
  [id]="id()"
828
1356
  [name]="name()"
829
1357
  [type]="computedType()"
1358
+ [value]="value"
1359
+ [disabled]="disabled()"
830
1360
  [required]="isRequired()"
831
1361
  [placeholder]="placeholder()"
832
- [formControl]="formControl"
1362
+ [autocomplete]="autocompleteAttr()"
833
1363
  (blur)="onTouched()"
1364
+ (input)="onInput($event)"
834
1365
  />
835
1366
 
836
1367
  @if (type() === 'password' && !loading() && !disabled()) {
@@ -891,8 +1422,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
891
1422
  class InputTextareaComponent extends FormControlBase {
892
1423
  rows = input(5);
893
1424
  cols = input(5);
894
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
895
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: InputTextareaComponent, isStandalone: true, selector: "nmf-textarea", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1425
+ onInput(event) {
1426
+ if (this._disabledByInput())
1427
+ return;
1428
+ const input = event.target;
1429
+ this.onChange(input.value);
1430
+ }
1431
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1432
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.25", type: InputTextareaComponent, isStandalone: true, selector: "nmf-textarea", inputs: { rows: { classPropertyName: "rows", publicName: "rows", isSignal: true, isRequired: false, transformFunction: null }, cols: { classPropertyName: "cols", publicName: "cols", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
896
1433
  <nmf-form-field
897
1434
  [label]="label()"
898
1435
  [isRequired]="isRequired()"
@@ -900,6 +1437,7 @@ class InputTextareaComponent extends FormControlBase {
900
1437
  [errorMessage]="errorMessage()"
901
1438
  >
902
1439
  <textarea
1440
+ #focusable
903
1441
  class="nmf-input"
904
1442
  [ngClass]="classList()"
905
1443
  [class.error]="hasErrors()"
@@ -907,15 +1445,18 @@ class InputTextareaComponent extends FormControlBase {
907
1445
  [id]="id()"
908
1446
  [rows]="rows()"
909
1447
  [cols]="cols()"
1448
+ [value]="value"
1449
+ [disabled]="disabled()"
910
1450
  [required]="isRequired()"
911
1451
  [placeholder]="placeholder()"
912
- [formControl]="formControl"
1452
+ [autocomplete]="autocompleteAttr()"
913
1453
  (blur)="onTouched()"
1454
+ (input)="onInput($event)"
914
1455
  ></textarea>
915
1456
  </nmf-form-field>
916
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1457
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
917
1458
  }
918
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTextareaComponent, decorators: [{
1459
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTextareaComponent, decorators: [{
919
1460
  type: Component,
920
1461
  args: [{
921
1462
  selector: 'nmf-textarea',
@@ -930,6 +1471,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
930
1471
  [errorMessage]="errorMessage()"
931
1472
  >
932
1473
  <textarea
1474
+ #focusable
933
1475
  class="nmf-input"
934
1476
  [ngClass]="classList()"
935
1477
  [class.error]="hasErrors()"
@@ -937,10 +1479,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
937
1479
  [id]="id()"
938
1480
  [rows]="rows()"
939
1481
  [cols]="cols()"
1482
+ [value]="value"
1483
+ [disabled]="disabled()"
940
1484
  [required]="isRequired()"
941
1485
  [placeholder]="placeholder()"
942
- [formControl]="formControl"
1486
+ [autocomplete]="autocompleteAttr()"
943
1487
  (blur)="onTouched()"
1488
+ (input)="onInput($event)"
944
1489
  ></textarea>
945
1490
  </nmf-form-field>
946
1491
  `,
@@ -979,8 +1524,8 @@ class InputTimepickerComponent extends FormControlBase {
979
1524
  this.displayValue.set(this.formatTime(parsed) ?? '');
980
1525
  this.onChange(parsed);
981
1526
  }
982
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTimepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
983
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.21", type: InputTimepickerComponent, isStandalone: true, selector: "nmf-timepicker", inputs: { step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
1527
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTimepickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
1528
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.25", type: InputTimepickerComponent, isStandalone: true, selector: "nmf-timepicker", inputs: { step: { classPropertyName: "step", publicName: "step", isSignal: true, isRequired: false, transformFunction: null } }, usesInheritance: true, ngImport: i0, template: `
984
1529
  <nmf-form-field
985
1530
  [label]="label()"
986
1531
  [isRequired]="isRequired()"
@@ -988,8 +1533,8 @@ class InputTimepickerComponent extends FormControlBase {
988
1533
  [errorMessage]="errorMessage()"
989
1534
  >
990
1535
  <input
1536
+ #focusable
991
1537
  type="time"
992
- autocomplete="off"
993
1538
  class="nmf-input"
994
1539
  [ngClass]="classList()"
995
1540
  [class.error]="hasErrors()"
@@ -1001,13 +1546,14 @@ class InputTimepickerComponent extends FormControlBase {
1001
1546
  [disabled]="disabled()"
1002
1547
  [required]="isRequired()"
1003
1548
  [placeholder]="placeholder()"
1549
+ [autocomplete]="autocompleteAttr()"
1004
1550
  (blur)="onTouched()"
1005
1551
  (input)="onInput($event)"
1006
1552
  />
1007
1553
  </nmf-form-field>
1008
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1554
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "component", type: FormFieldComponent, selector: "nmf-form-field", inputs: ["label", "isRequired", "loading", "hint", "errorMessage"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush });
1009
1555
  }
1010
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: InputTimepickerComponent, decorators: [{
1556
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: InputTimepickerComponent, decorators: [{
1011
1557
  type: Component,
1012
1558
  args: [{
1013
1559
  selector: 'nmf-timepicker',
@@ -1022,8 +1568,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
1022
1568
  [errorMessage]="errorMessage()"
1023
1569
  >
1024
1570
  <input
1571
+ #focusable
1025
1572
  type="time"
1026
- autocomplete="off"
1027
1573
  class="nmf-input"
1028
1574
  [ngClass]="classList()"
1029
1575
  [class.error]="hasErrors()"
@@ -1035,6 +1581,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
1035
1581
  [disabled]="disabled()"
1036
1582
  [required]="isRequired()"
1037
1583
  [placeholder]="placeholder()"
1584
+ [autocomplete]="autocompleteAttr()"
1038
1585
  (blur)="onTouched()"
1039
1586
  (input)="onInput($event)"
1040
1587
  />
@@ -1069,10 +1616,10 @@ class FormHydrator {
1069
1616
  control.patchValue(value, { emitEvent: false });
1070
1617
  });
1071
1618
  }
1072
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormHydrator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1073
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormHydrator, providedIn: 'root' });
1619
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormHydrator, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1620
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormHydrator, providedIn: 'root' });
1074
1621
  }
1075
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormHydrator, decorators: [{
1622
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormHydrator, decorators: [{
1076
1623
  type: Injectable,
1077
1624
  args: [{ providedIn: 'root' }]
1078
1625
  }] });
@@ -1092,10 +1639,10 @@ class FormSerializer {
1092
1639
  });
1093
1640
  return result;
1094
1641
  }
1095
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1096
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormSerializer, providedIn: 'root' });
1642
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormSerializer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1643
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormSerializer, providedIn: 'root' });
1097
1644
  }
1098
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormSerializer, decorators: [{
1645
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormSerializer, decorators: [{
1099
1646
  type: Injectable,
1100
1647
  args: [{ providedIn: 'root' }]
1101
1648
  }] });
@@ -1172,10 +1719,10 @@ class FormOrchestrator extends FormMapperBase {
1172
1719
  ngOnDestroy() {
1173
1720
  this._logicSubscription.unsubscribe();
1174
1721
  }
1175
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormOrchestrator, deps: [{ token: FormHydrator }, { token: FormSerializer }], target: i0.ɵɵFactoryTarget.Directive });
1176
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.21", type: FormOrchestrator, isStandalone: true, usesInheritance: true, ngImport: i0 });
1722
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormOrchestrator, deps: [{ token: FormHydrator }, { token: FormSerializer }], target: i0.ɵɵFactoryTarget.Directive });
1723
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.2.25", type: FormOrchestrator, isStandalone: true, usesInheritance: true, ngImport: i0 });
1177
1724
  }
1178
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImport: i0, type: FormOrchestrator, decorators: [{
1725
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.25", ngImport: i0, type: FormOrchestrator, decorators: [{
1179
1726
  type: Directive
1180
1727
  }], ctorParameters: () => [{ type: FormHydrator }, { type: FormSerializer }] });
1181
1728
 
@@ -1187,5 +1734,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.21", ngImpo
1187
1734
  * Generated bundle index. Do not edit.
1188
1735
  */
1189
1736
 
1190
- export { CurrencyBehavior, FormControlBase, FormHandlerBase, FormHydrator, FormMapperBase, FormOrchestrator, FormSerializer, InputCurrencyComponent, InputDatepickerComponent, InputNumberComponent, InputSelectComponent, InputTextComponent, InputTextareaComponent, InputTimepickerComponent, TextBehavior, formatNumber, getControl, getControlValue, parseNumber };
1737
+ export { CurrencyBehavior, FormControlBase, FormHandlerBase, FormHydrator, FormMapperBase, FormOrchestrator, FormSerializer, InputCurrencyComponent, InputDatepickerComponent, InputLookupComponent, InputNumberComponent, InputSelectComponent, InputTextComponent, InputTextareaComponent, InputTimepickerComponent, LookupBehavior, TextBehavior, formatNumber, getControl, getControlValue, parseNumber };
1191
1738
  //# sourceMappingURL=ng-modular-forms-core.mjs.map