@softpak/components 19.4.0 → 19.5.0-beta.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.
Files changed (87) hide show
  1. package/README.md +24 -24
  2. package/fesm2022/softpak-components-spx-alert.mjs +25 -159
  3. package/fesm2022/softpak-components-spx-alert.mjs.map +1 -1
  4. package/fesm2022/softpak-components-spx-app-configuration.mjs.map +1 -1
  5. package/fesm2022/softpak-components-spx-app-expiry.mjs +56 -56
  6. package/fesm2022/softpak-components-spx-app-expiry.mjs.map +1 -1
  7. package/fesm2022/softpak-components-spx-button.mjs +28 -111
  8. package/fesm2022/softpak-components-spx-button.mjs.map +1 -1
  9. package/fesm2022/softpak-components-spx-capitalize.mjs.map +1 -1
  10. package/fesm2022/softpak-components-spx-card.mjs +80 -293
  11. package/fesm2022/softpak-components-spx-card.mjs.map +1 -1
  12. package/fesm2022/softpak-components-spx-change-details.mjs +5 -5
  13. package/fesm2022/softpak-components-spx-change-details.mjs.map +1 -1
  14. package/fesm2022/softpak-components-spx-channel-selection.mjs +52 -52
  15. package/fesm2022/softpak-components-spx-channel-selection.mjs.map +1 -1
  16. package/fesm2022/softpak-components-spx-check-digit.mjs +3 -3
  17. package/fesm2022/softpak-components-spx-check-digit.mjs.map +1 -1
  18. package/fesm2022/softpak-components-spx-form-section.mjs +22 -22
  19. package/fesm2022/softpak-components-spx-form-section.mjs.map +1 -1
  20. package/fesm2022/softpak-components-spx-form-view.mjs +23 -202
  21. package/fesm2022/softpak-components-spx-form-view.mjs.map +1 -1
  22. package/fesm2022/softpak-components-spx-helpers.mjs.map +1 -1
  23. package/fesm2022/softpak-components-spx-inputs.mjs +441 -1286
  24. package/fesm2022/softpak-components-spx-inputs.mjs.map +1 -1
  25. package/fesm2022/softpak-components-spx-navigation.mjs +44 -44
  26. package/fesm2022/softpak-components-spx-navigation.mjs.map +1 -1
  27. package/fesm2022/softpak-components-spx-number-check.mjs +77 -79
  28. package/fesm2022/softpak-components-spx-number-check.mjs.map +1 -1
  29. package/fesm2022/softpak-components-spx-pagination.mjs +2 -2
  30. package/fesm2022/softpak-components-spx-pagination.mjs.map +1 -1
  31. package/fesm2022/softpak-components-spx-patch.mjs +25 -25
  32. package/fesm2022/softpak-components-spx-patch.mjs.map +1 -1
  33. package/fesm2022/softpak-components-spx-pipes.mjs +28 -0
  34. package/fesm2022/softpak-components-spx-pipes.mjs.map +1 -0
  35. package/fesm2022/softpak-components-spx-progress-bar.mjs +14 -14
  36. package/fesm2022/softpak-components-spx-progress-bar.mjs.map +1 -1
  37. package/fesm2022/softpak-components-spx-spinner.mjs +142 -142
  38. package/fesm2022/softpak-components-spx-spinner.mjs.map +1 -1
  39. package/fesm2022/softpak-components-spx-stock-info.mjs +2 -2
  40. package/fesm2022/softpak-components-spx-stock-info.mjs.map +1 -1
  41. package/fesm2022/softpak-components-spx-storage.mjs.map +1 -1
  42. package/fesm2022/softpak-components-spx-suggestion.mjs +3 -47
  43. package/fesm2022/softpak-components-spx-suggestion.mjs.map +1 -1
  44. package/fesm2022/softpak-components-spx-toaster.mjs +93 -93
  45. package/fesm2022/softpak-components-spx-toaster.mjs.map +1 -1
  46. package/fesm2022/softpak-components-spx-translate.mjs.map +1 -1
  47. package/fesm2022/softpak-components-spx-update.mjs +4 -7
  48. package/fesm2022/softpak-components-spx-update.mjs.map +1 -1
  49. package/fesm2022/softpak-components-spx-validation.mjs +2 -2
  50. package/fesm2022/softpak-components-spx-validation.mjs.map +1 -1
  51. package/package.json +30 -26
  52. package/spx-alert/spx-alert.component.d.ts +9 -14
  53. package/spx-button/spx-button.component.d.ts +15 -18
  54. package/spx-card/public-api.d.ts +3 -3
  55. package/spx-card/{spx-card-grid.component.d.ts → spx-card-grid/spx-card-grid.component.d.ts} +2 -2
  56. package/spx-card/spx-card-item/spx-card-item.component.d.ts +15 -0
  57. package/spx-card/spx-card-line/spx-card-line.component.d.ts +16 -0
  58. package/spx-change-details/spx-change-details.component.d.ts +2 -2
  59. package/spx-form-view/spx-autocomplete-search.component.d.ts +3 -4
  60. package/spx-form-view/spx-form-field.interface.d.ts +1 -1
  61. package/spx-form-view/spx-form-view.component.d.ts +10 -10
  62. package/spx-inputs/input.service.d.ts +12 -0
  63. package/spx-inputs/public-api.d.ts +2 -2
  64. package/spx-inputs/{spx-dropdown.component.d.ts → spx-dropdown/spx-dropdown.component.d.ts} +7 -7
  65. package/spx-inputs/spx-input-box/spx-input-box.component.d.ts +37 -0
  66. package/spx-inputs/spx-input-date/spx-input-date.component.d.ts +8 -4
  67. package/spx-inputs/spx-input-float/spx-input-float.component.d.ts +30 -0
  68. package/spx-inputs/spx-input-number/spx-input-number.component.d.ts +23 -0
  69. package/spx-inputs/spx-input-radio/spx-input-radio.component.d.ts +27 -0
  70. package/spx-inputs/spx-input-text/spx-input-text.component.d.ts +33 -0
  71. package/spx-inputs/spx-input-time/spx-input-time.component.d.ts +35 -0
  72. package/spx-inputs/{spx-input-time-modal.component.d.ts → spx-input-time-modal/spx-input-time-modal.component.d.ts} +6 -7
  73. package/spx-inputs/spx-input-type.enum.d.ts +2 -1
  74. package/spx-inputs/spx-input.component.d.ts +50 -49
  75. package/spx-number-check/spx-number-check.component.d.ts +1 -3
  76. package/spx-pipes/index.d.ts +5 -0
  77. package/spx-pipes/public-api.d.ts +1 -0
  78. package/spx-pipes/spx-severity-pipe.d.ts +8 -0
  79. package/tailwind.css +1 -1
  80. package/spx-card/spx-card-item.component.d.ts +0 -24
  81. package/spx-card/spx-card-line.component.d.ts +0 -17
  82. package/spx-inputs/spx-input-box.component.d.ts +0 -40
  83. package/spx-inputs/spx-input-float.component.d.ts +0 -30
  84. package/spx-inputs/spx-input-number.component.d.ts +0 -23
  85. package/spx-inputs/spx-input-radio.component.d.ts +0 -27
  86. package/spx-inputs/spx-input-text.component.d.ts +0 -31
  87. package/spx-inputs/spx-input-time.component.d.ts +0 -45
@@ -1,12 +1,12 @@
1
1
  import * as i0 from '@angular/core';
2
- import { EventEmitter, Component, Input, Output, HostListener, ViewChild, input, model, output, signal, viewChild, computed } from '@angular/core';
2
+ import { Injectable, inject, input, model, output, signal, Component, ChangeDetectionStrategy, HostListener, viewChild, computed } from '@angular/core';
3
3
  import { SpxButtonComponent } from '@softpak/components/spx-button';
4
4
  import * as i1 from '@fortawesome/angular-fontawesome';
5
5
  import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
6
6
  import { faEdit, faSearch, faQuestion, faTimes, faXmark } from '@fortawesome/free-solid-svg-icons';
7
- import { fromEvent } from 'rxjs';
7
+ import { BehaviorSubject, map, pairwise, filter, fromEvent } from 'rxjs';
8
8
  import * as i1$1 from '@angular/forms';
9
- import { FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
9
+ import { ReactiveFormsModule, FormsModule, NG_VALUE_ACCESSOR } from '@angular/forms';
10
10
  import { SpxSuggestionComponent } from '@softpak/components/spx-suggestion';
11
11
  import { valuePairToValue, SpxSeverityEnum } from '@softpak/components/spx-helpers';
12
12
  import { DateTime } from 'luxon';
@@ -14,25 +14,87 @@ import * as i1$2 from '@ionic/angular/standalone';
14
14
  import { IonButtons, IonContent, IonHeader, IonTitle, IonToolbar } from '@ionic/angular/standalone';
15
15
  import * as i1$3 from '@ionic/angular';
16
16
 
17
+ class SelectedInputService {
18
+ constructor() {
19
+ this.focusedElement = new BehaviorSubject(0); // Signal to store the selected input's ID
20
+ this.focusedElement$ = this.focusedElement.asObservable(); // Observable for the comparison result
21
+ }
22
+ isFocused$(id) {
23
+ return this.focusedElement$.pipe(map((focusedId) => {
24
+ return focusedId === id;
25
+ }) // Emit true/false if the element is focused
26
+ );
27
+ }
28
+ isBlurred$(id) {
29
+ return this.focusedElement$.pipe(pairwise(), // Emit both the previous and current value as a tuple
30
+ filter(([previous]) => {
31
+ // console.log("PREVIOUS:" + previous);
32
+ // console.log("NEXT: " + current);
33
+ // console.log("CURRENT ID: " + id)
34
+ return previous === id;
35
+ }), // Only proceed if the previous value matches the ID
36
+ map(([, current]) => {
37
+ return current === null;
38
+ }));
39
+ }
40
+ getSelectedElementId() {
41
+ return this.focusedElement.value; // Access the value directly from BehaviorSubject
42
+ }
43
+ // Method to update the selected ID
44
+ setSelectedElementId(id) {
45
+ this.focusedElement.next(id);
46
+ }
47
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SelectedInputService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
48
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SelectedInputService, providedIn: 'root' }); }
49
+ }
50
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SelectedInputService, decorators: [{
51
+ type: Injectable,
52
+ args: [{
53
+ providedIn: 'root', // Ensure the service is available globally
54
+ }]
55
+ }] });
56
+
17
57
  class SpxInputBoxComponent {
18
- handleFocusIn(ev) {
19
- this.emitFocusIn();
58
+ constructor() {
59
+ this.selectedInputService = inject(SelectedInputService);
60
+ this.faEdit = faEdit;
61
+ this.faSearch = faSearch;
62
+ this.faQuestion = faQuestion;
63
+ this.faTimes = faTimes;
64
+ this.spxCompact = input();
65
+ this.spxLabel = input();
66
+ this.spxReadonly = input(false);
67
+ this.spxRequired = input();
68
+ this.spxShowClear = input(true);
69
+ this.spxShowEdit = input();
70
+ this.spxShowHelp = input();
71
+ this.spxShowLabel = input(true);
72
+ this.spxShowSearch = input();
73
+ this.spxShowValidationMessages = input();
74
+ this.spxValue = model();
75
+ this.spxClear = output();
76
+ this.spxSearch = output();
77
+ this.spxEdit = output();
78
+ this.spxHelp = output();
79
+ this.id = signal(0);
80
+ this.spxIsFocused = signal(false);
81
+ this.spxSetIdInParent = output();
20
82
  }
21
- handleFocusOut(ev) {
22
- const thisEl = this.elRef.nativeElement;
23
- const relatedElement = ev.relatedTarget;
24
- if (!relatedElement || !thisEl.contains(relatedElement)) {
25
- this.emitFocusOut();
26
- }
83
+ ngOnInit() {
84
+ this.id.set(Math.random());
85
+ this.spxSetIdInParent.emit(this.id());
86
+ this.selectedInputService.isFocused$(this.id()).subscribe((isFocused) => {
87
+ this.spxIsFocused.set(isFocused);
88
+ });
27
89
  }
28
- handleWindowClick(ev) {
29
- if (ev.composedPath().includes(this.elRef.nativeElement)) {
30
- this.emitFocusIn();
31
- }
32
- else {
33
- this.emitFocusOut();
90
+ handleFocusIn(ev) {
91
+ if (this.selectedInputService.getSelectedElementId() != this.id()) {
92
+ this.selectedInputService.setSelectedElementId(this.id());
34
93
  }
35
94
  }
95
+ handleFocusOut(ev) {
96
+ this.selectedInputService.setSelectedElementId(null);
97
+ }
36
98
  onClear() {
37
99
  this.spxClear.emit();
38
100
  }
@@ -45,252 +107,36 @@ class SpxInputBoxComponent {
45
107
  onHelp() {
46
108
  this.spxHelp.emit();
47
109
  }
48
- constructor(elRef) {
49
- this.elRef = elRef;
50
- this.faEdit = faEdit;
51
- this.faSearch = faSearch;
52
- this.faQuestion = faQuestion;
53
- this.faTimes = faTimes;
54
- this.spxFocused = false;
55
- this.spxReadonly = false;
56
- this.spxShowClear = true;
57
- this.spxShowLabel = true;
58
- this.spxClear = new EventEmitter();
59
- this.spxSearch = new EventEmitter();
60
- this.spxFocus = new EventEmitter();
61
- this.spxFocusOut = new EventEmitter();
62
- this.spxEdit = new EventEmitter();
63
- this.spxHelp = new EventEmitter();
64
- }
65
- emitFocusIn() {
66
- if (!this.spxFocused) {
67
- this.spxFocus.emit();
68
- }
69
- }
70
- emitFocusOut() {
71
- if (this.spxFocused) {
72
- this.spxFocusOut.emit();
73
- }
74
- }
75
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputBoxComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
76
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputBoxComponent, isStandalone: true, selector: "spx-input-box", inputs: { spxCompact: "spxCompact", spxFocused: "spxFocused", spxLabel: "spxLabel", spxReadonly: "spxReadonly", spxRequired: "spxRequired", spxShowClear: "spxShowClear", spxShowEdit: "spxShowEdit", spxShowHelp: "spxShowHelp", spxShowLabel: "spxShowLabel", spxShowSearch: "spxShowSearch", spxShowValidationMessages: "spxShowValidationMessages", spxValue: "spxValue" }, outputs: { spxClear: "spxClear", spxSearch: "spxSearch", spxFocus: "spxFocus", spxFocusOut: "spxFocusOut", spxEdit: "spxEdit", spxHelp: "spxHelp" }, host: { listeners: { "focusin": "handleFocusIn($event)", "focusout": "handleFocusOut($event)", "document:click": "handleWindowClick($event)" } }, ngImport: i0, template: `<div class="flex rounded w-full gap-3"
77
- [class.rounded-none]="this.spxShowValidationMessages"
78
- [class.rounded-t]="this.spxShowValidationMessages"
79
- [class.outline-none]="this.spxFocused && !this.spxReadonly"
80
- [class.ring-2]="this.spxFocused && !this.spxReadonly"
81
- [class.ring-offset-2]="this.spxFocused && !this.spxReadonly"
82
- [class.ring-blue-500]="this.spxFocused && !this.spxReadonly"
83
- [class.bg-white]="!this.spxReadonly"
84
- [class.bg-gray-300]="this.spxReadonly"
85
- [class.cursor-not-allowed]="this.spxReadonly">
86
- <div class="flex-auto p-3"
87
- [class.p-0]="this.spxCompact"
88
- [class.flex]="this.spxCompact"
89
- [class.items-center]="this.spxCompact">
90
- @if (this.spxShowLabel) {
91
- <div class="font-bold text-sm mb-1 text-gray-800"
92
- [class.mb-0]="this.spxCompact"
93
- [class.px-3]="this.spxCompact">
94
- {{this.spxLabel}} @if (spxRequired) {
95
- <span class="text-red-800">*</span>
96
- }
97
- </div>
98
- }
99
- <ng-content select="[controls]"></ng-content>
100
- </div>
101
- <div class="flex flex-none gap-1 p-1">
102
- @if (this.spxShowEdit) {
103
- <spx-button
104
- (spxClick)="onEdit()"
105
- [spxFullHeight]="true"
106
- [spxSize]="'xl'"
107
- [spxType]="'button'">
108
- <fa-icon [icon]="faEdit" class="block text-xl"></fa-icon>
109
- </spx-button>
110
- }
111
- @if (this.spxShowHelp) {
112
- <spx-button
113
- (spxClick)="onHelp()"
114
- [spxFullHeight]="true"
115
- [spxDisabled]="this.spxReadonly"
116
- [spxSize]="'xl'"
117
- [spxTabIndex]="-1"
118
- [spxType]="'button'">
119
- <fa-icon [icon]="faQuestion" class="block text-xl"></fa-icon>
120
- </spx-button>
121
- }
122
- @if (this.spxShowSearch) {
123
- <spx-button
124
- (spxClick)="onSearch()"
125
- [spxFullHeight]="true"
126
- [spxDisabled]="this.spxReadonly"
127
- [spxSize]="'xl'"
128
- [spxTabIndex]="-1"
129
- [spxType]="'button'">
130
- <fa-icon [icon]="faSearch" class="block text-xl"></fa-icon>
131
- </spx-button>
132
- }
133
- @if (this.spxShowClear) {
134
- <spx-button
135
- (spxClick)="onClear()"
136
- [spxDisabled]="this.spxReadonly || !this.spxValue?.value"
137
- [spxFullHeight]="true"
138
- [spxSize]="'xl'"
139
- [spxTabIndex]="-1"
140
- [spxType]="'button'">
141
- <fa-icon [icon]="faTimes" class="block text-xl"></fa-icon>
142
- </spx-button>
143
- }
144
- </div>
145
- </div>
146
- @if (this.spxShowValidationMessages) {
147
- <div class="bg-red-600 rounded-b text-white p-3">
148
- <ng-content select="[validation-messages]"></ng-content>
149
- </div>
150
- }`, isInline: true, dependencies: [{ kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }] }); }
110
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputBoxComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
111
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputBoxComponent, isStandalone: true, selector: "spx-input-box", inputs: { spxCompact: { classPropertyName: "spxCompact", publicName: "spxCompact", isSignal: true, isRequired: false, transformFunction: null }, spxLabel: { classPropertyName: "spxLabel", publicName: "spxLabel", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxRequired: { classPropertyName: "spxRequired", publicName: "spxRequired", isSignal: true, isRequired: false, transformFunction: null }, spxShowClear: { classPropertyName: "spxShowClear", publicName: "spxShowClear", isSignal: true, isRequired: false, transformFunction: null }, spxShowEdit: { classPropertyName: "spxShowEdit", publicName: "spxShowEdit", isSignal: true, isRequired: false, transformFunction: null }, spxShowHelp: { classPropertyName: "spxShowHelp", publicName: "spxShowHelp", isSignal: true, isRequired: false, transformFunction: null }, spxShowLabel: { classPropertyName: "spxShowLabel", publicName: "spxShowLabel", isSignal: true, isRequired: false, transformFunction: null }, spxShowSearch: { classPropertyName: "spxShowSearch", publicName: "spxShowSearch", isSignal: true, isRequired: false, transformFunction: null }, spxShowValidationMessages: { classPropertyName: "spxShowValidationMessages", publicName: "spxShowValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, spxValue: { classPropertyName: "spxValue", publicName: "spxValue", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { spxValue: "spxValueChange", spxClear: "spxClear", spxSearch: "spxSearch", spxEdit: "spxEdit", spxHelp: "spxHelp", spxSetIdInParent: "spxSetIdInParent" }, host: { listeners: { "click": "handleFocusIn()", "focusin": "handleFocusIn($event)", "focusout": "handleFocusOut($event)" } }, ngImport: i0, template: "<div class=\"flex rounded w-full gap-3\"\r\n [class.rounded-none]=\"this.spxShowValidationMessages()\"\r\n [class.rounded-t]=\"this.spxShowValidationMessages()\"\r\n [class.outline-none]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-2]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-offset-2]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-blue-500]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.bg-white]=\"!this.spxReadonly()\"\r\n [class.bg-gray-300]=\"this.spxReadonly()\"\r\n [class.cursor-not-allowed]=\"this.spxReadonly()\"\r\n \r\n >\r\n <div class=\"flex-auto p-3\"\r\n [class.p-0]=\"this.spxCompact()\"\r\n [class.flex]=\"this.spxCompact()\"\r\n [class.items-center]=\"this.spxCompact()\">\r\n @if (this.spxShowLabel()) {\r\n <div class=\"font-bold text-sm mb-1 text-gray-800\"\r\n [class.mb-0]=\"this.spxCompact()\"\r\n [class.px-3]=\"this.spxCompact()\">\r\n {{this.spxLabel()}} @if (spxRequired()) {\r\n <span class=\"text-red-800\">*</span>\r\n }\r\n </div>\r\n }\r\n\r\n <ng-content select=\"[controls]\"></ng-content>\r\n </div>\r\n <div class=\"flex flex-none gap-1 p-1\">\r\n @if (this.spxShowEdit()) {\r\n <spx-button\r\n (spxClick)=\"onEdit()\"\r\n [spxFullHeight]=\"true\"\r\n [spxSize]=\"'xl'\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faEdit\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowHelp()) {\r\n <spx-button\r\n (spxClick)=\"onHelp()\"\r\n [spxFullHeight]=\"true\"\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faQuestion\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowSearch()) {\r\n <spx-button\r\n (spxClick)=\"onSearch()\"\r\n [spxFullHeight]=\"true\"\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faSearch\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowClear()) {\r\n <spx-button\r\n (spxClick)=\"onClear()\"\r\n [spxDisabled]=\"this.spxReadonly() || (this.spxValue()?.description !== 'No' && !this.spxValue()?.value)\"\r\n [spxFullHeight]=\"true\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faTimes\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n </div>\r\n </div>\r\n @if (this.spxShowValidationMessages()) {\r\n <div class=\"bg-red-600 rounded-b text-white p-3\">\r\n <ng-content select=\"[validation-messages]\"></ng-content>\r\n </div>\r\n }", dependencies: [{ kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }, { kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
151
112
  }
152
113
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputBoxComponent, decorators: [{
153
114
  type: Component,
154
- args: [{
155
- selector: 'spx-input-box',
156
- imports: [
115
+ args: [{ selector: 'spx-input-box', imports: [
157
116
  SpxButtonComponent,
158
117
  FontAwesomeModule
159
- ],
160
- template: `<div class="flex rounded w-full gap-3"
161
- [class.rounded-none]="this.spxShowValidationMessages"
162
- [class.rounded-t]="this.spxShowValidationMessages"
163
- [class.outline-none]="this.spxFocused && !this.spxReadonly"
164
- [class.ring-2]="this.spxFocused && !this.spxReadonly"
165
- [class.ring-offset-2]="this.spxFocused && !this.spxReadonly"
166
- [class.ring-blue-500]="this.spxFocused && !this.spxReadonly"
167
- [class.bg-white]="!this.spxReadonly"
168
- [class.bg-gray-300]="this.spxReadonly"
169
- [class.cursor-not-allowed]="this.spxReadonly">
170
- <div class="flex-auto p-3"
171
- [class.p-0]="this.spxCompact"
172
- [class.flex]="this.spxCompact"
173
- [class.items-center]="this.spxCompact">
174
- @if (this.spxShowLabel) {
175
- <div class="font-bold text-sm mb-1 text-gray-800"
176
- [class.mb-0]="this.spxCompact"
177
- [class.px-3]="this.spxCompact">
178
- {{this.spxLabel}} @if (spxRequired) {
179
- <span class="text-red-800">*</span>
180
- }
181
- </div>
182
- }
183
- <ng-content select="[controls]"></ng-content>
184
- </div>
185
- <div class="flex flex-none gap-1 p-1">
186
- @if (this.spxShowEdit) {
187
- <spx-button
188
- (spxClick)="onEdit()"
189
- [spxFullHeight]="true"
190
- [spxSize]="'xl'"
191
- [spxType]="'button'">
192
- <fa-icon [icon]="faEdit" class="block text-xl"></fa-icon>
193
- </spx-button>
194
- }
195
- @if (this.spxShowHelp) {
196
- <spx-button
197
- (spxClick)="onHelp()"
198
- [spxFullHeight]="true"
199
- [spxDisabled]="this.spxReadonly"
200
- [spxSize]="'xl'"
201
- [spxTabIndex]="-1"
202
- [spxType]="'button'">
203
- <fa-icon [icon]="faQuestion" class="block text-xl"></fa-icon>
204
- </spx-button>
205
- }
206
- @if (this.spxShowSearch) {
207
- <spx-button
208
- (spxClick)="onSearch()"
209
- [spxFullHeight]="true"
210
- [spxDisabled]="this.spxReadonly"
211
- [spxSize]="'xl'"
212
- [spxTabIndex]="-1"
213
- [spxType]="'button'">
214
- <fa-icon [icon]="faSearch" class="block text-xl"></fa-icon>
215
- </spx-button>
216
- }
217
- @if (this.spxShowClear) {
218
- <spx-button
219
- (spxClick)="onClear()"
220
- [spxDisabled]="this.spxReadonly || !this.spxValue?.value"
221
- [spxFullHeight]="true"
222
- [spxSize]="'xl'"
223
- [spxTabIndex]="-1"
224
- [spxType]="'button'">
225
- <fa-icon [icon]="faTimes" class="block text-xl"></fa-icon>
226
- </spx-button>
227
- }
228
- </div>
229
- </div>
230
- @if (this.spxShowValidationMessages) {
231
- <div class="bg-red-600 rounded-b text-white p-3">
232
- <ng-content select="[validation-messages]"></ng-content>
233
- </div>
234
- }`
235
- }]
236
- }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { spxCompact: [{
237
- type: Input
238
- }], spxFocused: [{
239
- type: Input
240
- }], spxLabel: [{
241
- type: Input
242
- }], spxReadonly: [{
243
- type: Input
244
- }], spxRequired: [{
245
- type: Input
246
- }], spxShowClear: [{
247
- type: Input
248
- }], spxShowEdit: [{
249
- type: Input
250
- }], spxShowHelp: [{
251
- type: Input
252
- }], spxShowLabel: [{
253
- type: Input
254
- }], spxShowSearch: [{
255
- type: Input
256
- }], spxShowValidationMessages: [{
257
- type: Input
258
- }], spxValue: [{
259
- type: Input
260
- }], spxClear: [{
261
- type: Output
262
- }], spxSearch: [{
263
- type: Output
264
- }], spxFocus: [{
265
- type: Output
266
- }], spxFocusOut: [{
267
- type: Output
268
- }], spxEdit: [{
269
- type: Output
270
- }], spxHelp: [{
271
- type: Output
272
- }], handleFocusIn: [{
118
+ ], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: {
119
+ "(click)": "handleFocusIn()"
120
+ }, template: "<div class=\"flex rounded w-full gap-3\"\r\n [class.rounded-none]=\"this.spxShowValidationMessages()\"\r\n [class.rounded-t]=\"this.spxShowValidationMessages()\"\r\n [class.outline-none]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-2]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-offset-2]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.ring-blue-500]=\"this.spxIsFocused() && !this.spxReadonly()\"\r\n [class.bg-white]=\"!this.spxReadonly()\"\r\n [class.bg-gray-300]=\"this.spxReadonly()\"\r\n [class.cursor-not-allowed]=\"this.spxReadonly()\"\r\n \r\n >\r\n <div class=\"flex-auto p-3\"\r\n [class.p-0]=\"this.spxCompact()\"\r\n [class.flex]=\"this.spxCompact()\"\r\n [class.items-center]=\"this.spxCompact()\">\r\n @if (this.spxShowLabel()) {\r\n <div class=\"font-bold text-sm mb-1 text-gray-800\"\r\n [class.mb-0]=\"this.spxCompact()\"\r\n [class.px-3]=\"this.spxCompact()\">\r\n {{this.spxLabel()}} @if (spxRequired()) {\r\n <span class=\"text-red-800\">*</span>\r\n }\r\n </div>\r\n }\r\n\r\n <ng-content select=\"[controls]\"></ng-content>\r\n </div>\r\n <div class=\"flex flex-none gap-1 p-1\">\r\n @if (this.spxShowEdit()) {\r\n <spx-button\r\n (spxClick)=\"onEdit()\"\r\n [spxFullHeight]=\"true\"\r\n [spxSize]=\"'xl'\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faEdit\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowHelp()) {\r\n <spx-button\r\n (spxClick)=\"onHelp()\"\r\n [spxFullHeight]=\"true\"\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faQuestion\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowSearch()) {\r\n <spx-button\r\n (spxClick)=\"onSearch()\"\r\n [spxFullHeight]=\"true\"\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faSearch\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n @if (this.spxShowClear()) {\r\n <spx-button\r\n (spxClick)=\"onClear()\"\r\n [spxDisabled]=\"this.spxReadonly() || (this.spxValue()?.description !== 'No' && !this.spxValue()?.value)\"\r\n [spxFullHeight]=\"true\"\r\n [spxSize]=\"'xl'\"\r\n [spxTabIndex]=\"-1\"\r\n [spxType]=\"'button'\">\r\n <fa-icon [icon]=\"faTimes\" class=\"block text-xl\"></fa-icon>\r\n </spx-button>\r\n }\r\n </div>\r\n </div>\r\n @if (this.spxShowValidationMessages()) {\r\n <div class=\"bg-red-600 rounded-b text-white p-3\">\r\n <ng-content select=\"[validation-messages]\"></ng-content>\r\n </div>\r\n }" }]
121
+ }], propDecorators: { handleFocusIn: [{
273
122
  type: HostListener,
274
123
  args: ['focusin', ["$event"]]
275
124
  }], handleFocusOut: [{
276
125
  type: HostListener,
277
126
  args: ['focusout', ["$event"]]
278
- }], handleWindowClick: [{
279
- type: HostListener,
280
- args: ['document:click', ["$event"]]
281
127
  }] } });
282
128
 
283
129
  class SpxDropdownComponent {
284
130
  constructor() {
285
- this.focusPosition = 0;
286
- this.spxSuggestions = [];
287
- this.spxSelect = new EventEmitter();
131
+ this.focusPosition = signal(0);
132
+ this.spxSuggestions = input([]);
133
+ this.spxSelect = output();
288
134
  }
289
135
  ngOnInit() {
290
136
  this.listenToKeyUp();
291
137
  }
292
- ngOnChanges(changes) {
293
- this.focusPosition = 0;
138
+ ngOnChanges(_changes) {
139
+ this.focusPosition.set(0);
294
140
  }
295
141
  ngOnDestroy() {
296
142
  this.subscriptionKeyUp?.unsubscribe();
@@ -300,525 +146,312 @@ class SpxDropdownComponent {
300
146
  }
301
147
  listenToKeyUp() {
302
148
  this.subscriptionKeyUp = fromEvent(window, 'keyup').subscribe((event) => {
303
- if (event.key === 'ArrowUp' && this.focusPosition > 0) {
304
- this.focusPosition = this.focusPosition - 1;
149
+ if (event.key === 'ArrowUp' && this.focusPosition() > 0) {
150
+ this.focusPosition.update((oldValue) => oldValue - 1);
305
151
  event.preventDefault();
306
152
  }
307
- if (event.key === 'ArrowDown' && this.focusPosition < this.spxSuggestions.length - 1) {
308
- this.focusPosition = this.focusPosition + 1;
153
+ if (event.key === 'ArrowDown' && this.focusPosition() < this.spxSuggestions().length - 1) {
154
+ this.focusPosition.update((oldValue) => oldValue + 1);
309
155
  event.preventDefault();
310
156
  }
311
- if (event.key === 'Enter' && this.spxSuggestions.length > 0) {
312
- this.select(this.spxSuggestions.at(this.focusPosition));
157
+ if (event.key === 'Enter' && this.spxSuggestions().length > 0) {
158
+ this.select(this.spxSuggestions().at(this.focusPosition()));
313
159
  event.preventDefault();
314
160
  }
315
161
  });
316
162
  }
317
163
  select(valuePair) {
318
- this.focusPosition = 0;
164
+ this.focusPosition.set(0);
319
165
  this.spxSelect.emit(valuePair);
320
166
  }
321
167
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxDropdownComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
322
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxDropdownComponent, isStandalone: true, selector: "spx-dropdown", inputs: { spxSuggestions: "spxSuggestions" }, outputs: { spxSelect: "spxSelect" }, usesOnChanges: true, ngImport: i0, template: `<div class="relative text-black">
323
- <div
324
- class="absolute bg-gray-100 left-0 right-0 z-20">
325
- @for (valuePair of this.spxSuggestions; track valuePair; let i = $index) {
326
- <button
327
- class="text-black block w-full p-2 border border-gray-200 rounded-lg shadow hover:bg-gray-200 flex items-center text-left"
328
- [class.bg-gray-100]="i === this.focusPosition"
329
- [class.bg-white]="i !== this.focusPosition"
330
- (click)="this.handleSuggestionClick(valuePair)"
331
- [attr.tabindex]="-1"
332
- [attr.type]="'button'">
333
- <div class="flex-1 p-1 font-bold text-lg">{{valuePair?.description}}</div>
334
- <spx-button (spxClick)="this.handleSuggestionClick(valuePair)" [spxType]="'button'" [spxTabIndex]="-1">Select</spx-button>
335
- </button>
336
- }
337
- </div>
338
- </div>`, isInline: true, dependencies: [{ kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }] }); }
168
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxDropdownComponent, isStandalone: true, selector: "spx-dropdown", inputs: { spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { spxSelect: "spxSelect" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"relative text-black\">\r\n <div\r\n class=\"absolute bg-gray-100 left-0 right-0 z-20\">\r\n @for (valuePair of this.spxSuggestions(); track valuePair; let i = $index) {\r\n <button\r\n class=\"text-black block w-full p-2 border border-gray-200 rounded-lg shadow hover:bg-gray-200 flex items-center text-left\"\r\n [class.bg-gray-100]=\"i === this.focusPosition()\"\r\n [class.bg-white]=\"i !== this.focusPosition()\"\r\n (click)=\"this.handleSuggestionClick(valuePair)\"\r\n [attr.tabindex]=\"-1\"\r\n [attr.type]=\"'button'\">\r\n <div class=\"flex-1 p-1 font-bold text-lg\">{{valuePair?.description}}</div>\r\n <spx-button (spxClick)=\"this.handleSuggestionClick(valuePair)\" [spxType]=\"'button'\" [spxTabIndex]=\"-1\">Select</spx-button>\r\n </button>\r\n }\r\n </div>\r\n</div>", dependencies: [{ kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
339
169
  }
340
170
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxDropdownComponent, decorators: [{
341
171
  type: Component,
342
- args: [{
343
- selector: 'spx-dropdown',
344
- imports: [
172
+ args: [{ selector: 'spx-dropdown', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [
345
173
  SpxButtonComponent
346
- ],
347
- template: `<div class="relative text-black">
348
- <div
349
- class="absolute bg-gray-100 left-0 right-0 z-20">
350
- @for (valuePair of this.spxSuggestions; track valuePair; let i = $index) {
351
- <button
352
- class="text-black block w-full p-2 border border-gray-200 rounded-lg shadow hover:bg-gray-200 flex items-center text-left"
353
- [class.bg-gray-100]="i === this.focusPosition"
354
- [class.bg-white]="i !== this.focusPosition"
355
- (click)="this.handleSuggestionClick(valuePair)"
356
- [attr.tabindex]="-1"
357
- [attr.type]="'button'">
358
- <div class="flex-1 p-1 font-bold text-lg">{{valuePair?.description}}</div>
359
- <spx-button (spxClick)="this.handleSuggestionClick(valuePair)" [spxType]="'button'" [spxTabIndex]="-1">Select</spx-button>
360
- </button>
361
- }
362
- </div>
363
- </div>`
364
- }]
365
- }], propDecorators: { spxSuggestions: [{
366
- type: Input
367
- }], spxSelect: [{
368
- type: Output
369
- }] } });
174
+ ], template: "<div class=\"relative text-black\">\r\n <div\r\n class=\"absolute bg-gray-100 left-0 right-0 z-20\">\r\n @for (valuePair of this.spxSuggestions(); track valuePair; let i = $index) {\r\n <button\r\n class=\"text-black block w-full p-2 border border-gray-200 rounded-lg shadow hover:bg-gray-200 flex items-center text-left\"\r\n [class.bg-gray-100]=\"i === this.focusPosition()\"\r\n [class.bg-white]=\"i !== this.focusPosition()\"\r\n (click)=\"this.handleSuggestionClick(valuePair)\"\r\n [attr.tabindex]=\"-1\"\r\n [attr.type]=\"'button'\">\r\n <div class=\"flex-1 p-1 font-bold text-lg\">{{valuePair?.description}}</div>\r\n <spx-button (spxClick)=\"this.handleSuggestionClick(valuePair)\" [spxType]=\"'button'\" [spxTabIndex]=\"-1\">Select</spx-button>\r\n </button>\r\n }\r\n </div>\r\n</div>" }]
175
+ }] });
176
+
177
+ var SpxInputTypeEnum;
178
+ (function (SpxInputTypeEnum) {
179
+ SpxInputTypeEnum["autocomplete"] = "autocomplete";
180
+ SpxInputTypeEnum["button"] = "button";
181
+ SpxInputTypeEnum["date"] = "date";
182
+ SpxInputTypeEnum["float"] = "float";
183
+ SpxInputTypeEnum["hidden"] = "hidden";
184
+ SpxInputTypeEnum["overlay"] = "overlay";
185
+ SpxInputTypeEnum["overlayNumber"] = "overlaynumber";
186
+ SpxInputTypeEnum["radio"] = "radio";
187
+ SpxInputTypeEnum["number"] = "number";
188
+ SpxInputTypeEnum["password"] = "password";
189
+ SpxInputTypeEnum["text"] = "text";
190
+ SpxInputTypeEnum["textNumericKeyboard"] = "textNumericKeyboard";
191
+ SpxInputTypeEnum["time"] = "time";
192
+ SpxInputTypeEnum["dropdown"] = "dropdown";
193
+ })(SpxInputTypeEnum || (SpxInputTypeEnum = {}));
370
194
 
371
195
  class SpxInputTextComponent {
372
196
  constructor() {
373
- this.spxAutofocus = false;
374
- this.spxSuggestions = [];
375
- this.spxReadonly = false;
376
- this.spxCapitalize = false;
377
- this.spxFocused = true;
378
- this.spxType = 'text';
379
- this.spxBlurFromChild = new EventEmitter();
380
- this.spxChange = new EventEmitter();
381
- this.spxFocus = new EventEmitter();
382
- this.spxWasInternalUpdate = false;
197
+ this.spxName = input();
198
+ this.spxAutofocus = input(false);
199
+ this.spxAutocomplete = input();
200
+ this.spxInputMode = input();
201
+ this.spxPattern = input();
202
+ this.spxSuggestions = input([]);
203
+ this.spxReadonly = input(false);
204
+ this.spxValidators = input();
205
+ this.spxCapitalize = input(false);
206
+ this.spxType = input(SpxInputTypeEnum.text);
207
+ this.spxWasInternalUpdate = input(false);
208
+ this.inputRef = viewChild.required('input');
209
+ this.spxBlurFromChild = output();
210
+ this.value = model.required();
211
+ this.valueChange = output();
212
+ this.spxElementId = input();
213
+ this.selectedInputService = inject(SelectedInputService);
214
+ this.spxIsFocused = signal(false);
215
+ }
216
+ ngOnInit() {
217
+ this.componentDidLoad();
218
+ // Filter updates based on focus state
219
+ this.selectedInputService.focusedElement$
220
+ .pipe(filter((focusedId) => focusedId === this.spxElementId()))
221
+ .subscribe(() => {
222
+ this.spxIsFocused.set(true); // Update only if focused
223
+ this.spxSetFocus();
224
+ });
383
225
  }
384
226
  spxSetFocus() {
385
- this.inputRef?.nativeElement?.focus();
227
+ this.inputRef().nativeElement?.focus();
386
228
  }
387
229
  componentDidLoad() {
388
- if (this.spxAutofocus) {
389
- this.spxFocus.emit();
230
+ if (this.spxAutofocus()) {
390
231
  this.spxSetFocus();
391
232
  }
392
233
  }
393
- handleBlur() {
394
- this.spxBlurFromChild.emit();
395
- }
396
- handleFocus() {
397
- this.spxFocus.emit();
234
+ handleChange($event) {
235
+ this.value.set({ ...this.value(), value: $event });
236
+ this.valueChange.emit(this.value()); // Emit the updated value to the parent
398
237
  }
399
238
  handleDescriptionInput(event) {
400
- this.value = {
239
+ this.value.set({
401
240
  description: event.target ? event.target.value : null,
402
241
  value: event.target ? event.target.value : null,
403
- };
404
- this.spxChange.emit(this.value);
242
+ });
405
243
  }
406
244
  handleSuggestionClick(value) {
407
- if (!this.spxReadonly) {
408
- this.value = value;
409
- this.spxChange.emit(this.value);
410
- this.spxFocused = false;
245
+ if (!this.spxReadonly()) {
246
+ this.value.set(value);
411
247
  }
412
248
  }
413
- handleKeyUp() {
414
- this.spxFocused = true;
415
- }
416
249
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTextComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
417
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputTextComponent, isStandalone: true, selector: "spx-input-text", inputs: { spxName: "spxName", spxAutofocus: "spxAutofocus", spxAutocomplete: "spxAutocomplete", spxInputMode: "spxInputMode", spxPattern: "spxPattern", spxSuggestions: "spxSuggestions", spxReadonly: "spxReadonly", spxValidators: "spxValidators", spxCapitalize: "spxCapitalize", spxFocused: "spxFocused", spxType: "spxType", value: "value", spxWasInternalUpdate: "spxWasInternalUpdate" }, outputs: { spxBlurFromChild: "spxBlurFromChild", spxChange: "spxChange", spxFocus: "spxFocus" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, static: true }], ngImport: i0, template: `<div class="relative text-black">
418
- <input
419
- #input
420
- class="font-bold text-lg w-full outline-none"
421
- autocomplete="off"
422
- spellcheck="false"
423
- [class.bg-white]="!this.spxReadonly"
424
- [class.bg-gray-300]="this.spxReadonly"
425
- [class.cursor-not-allowed]="this.spxReadonly"
426
- [class.uppercase]="this.spxCapitalize"
427
- [attr.autocomplete]="this.spxAutocomplete ? this.spxAutocomplete : undefined"
428
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
429
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
430
- [attr.inputMode]="this.spxInputMode ? this.spxInputMode : undefined"
431
- [attr.pattern]="this.spxPattern ? this.spxPattern : undefined"
432
- [attr.name]="this.spxName"
433
- [attr.type]="this.spxType"
434
- [value]="this.value?.description ? this.value?.description : this.value?.value"
435
- (blur)="this.handleBlur()"
436
- (keyUp)="this.handleKeyUp()"
437
- (focus)="this.handleFocus()"
438
- (input)="this.handleDescriptionInput($event)"
439
- />
440
- @if (this.value?.description && this.value?.value && this.value?.description?.valueOf() !== this.value?.value?.valueOf()) {
441
- <span>{{this.value?.value}}</span>
442
- }
443
- @if (this.spxFocused && (this.spxType === 'overlay' || this.spxType === 'overlaynumber')) {
444
- <spx-dropdown
445
- [spxSuggestions]="this.spxSuggestions" (spxSelect)="this.handleSuggestionClick($event)">
446
- </spx-dropdown>
447
- }
448
- </div>`, isInline: true, dependencies: [{ kind: "component", type: SpxDropdownComponent, selector: "spx-dropdown", inputs: ["spxSuggestions"], outputs: ["spxSelect"] }] }); }
250
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputTextComponent, isStandalone: true, selector: "spx-input-text", inputs: { spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxAutofocus: { classPropertyName: "spxAutofocus", publicName: "spxAutofocus", isSignal: true, isRequired: false, transformFunction: null }, spxAutocomplete: { classPropertyName: "spxAutocomplete", publicName: "spxAutocomplete", isSignal: true, isRequired: false, transformFunction: null }, spxInputMode: { classPropertyName: "spxInputMode", publicName: "spxInputMode", isSignal: true, isRequired: false, transformFunction: null }, spxPattern: { classPropertyName: "spxPattern", publicName: "spxPattern", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxCapitalize: { classPropertyName: "spxCapitalize", publicName: "spxCapitalize", isSignal: true, isRequired: false, transformFunction: null }, spxType: { classPropertyName: "spxType", publicName: "spxType", isSignal: true, isRequired: false, transformFunction: null }, spxWasInternalUpdate: { classPropertyName: "spxWasInternalUpdate", publicName: "spxWasInternalUpdate", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, spxElementId: { classPropertyName: "spxElementId", publicName: "spxElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { spxBlurFromChild: "spxBlurFromChild", value: "valueChange", valueChange: "valueChange" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative text-black\">\r\n <input\r\n #input\r\n class=\"font-bold text-lg w-full outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [class.bg-white]=\"!this.spxReadonly()\"\r\n [class.bg-gray-300]=\"this.spxReadonly()\"\r\n [class.cursor-not-allowed]=\"this.spxReadonly()\"\r\n [class.uppercase]=\"this.spxCapitalize()\"\r\n [attr.autocomplete]=\"this.spxAutocomplete()\"\r\n [attr.autofocus]=\"this.spxAutofocus()\"\r\n [attr.disabled]=\"this.spxReadonly()\"\r\n [attr.inputMode]=\"this.spxInputMode()\"\r\n [attr.pattern]=\"this.spxPattern()\"\r\n [attr.name]=\"this.spxName()\"\r\n [attr.type]=\"this.spxType()\"\r\n [ngModel]=\"this.value().description ? this.value().description : this.value().value\"\r\n (ngModelChange)=\"this.handleChange($event)\"\r\n />\r\n\r\n @if (this.value().description && this.value().value && this.value().description?.valueOf() !== this.value().value?.valueOf()) {\r\n <span>{{this.value().value}}</span>\r\n }\r\n @if (this.spxIsFocused() && (this.spxType() === 'overlay' || this.spxType() === 'overlaynumber')) {\r\n <spx-dropdown\r\n [spxSuggestions]=\"this.spxSuggestions()\" (spxSelect)=\"this.handleSuggestionClick($event)\">\r\n </spx-dropdown>\r\n }\r\n</div>", dependencies: [{ kind: "component", type: SpxDropdownComponent, selector: "spx-dropdown", inputs: ["spxSuggestions"], outputs: ["spxSelect"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
449
251
  }
450
252
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTextComponent, decorators: [{
451
253
  type: Component,
452
- args: [{
453
- selector: 'spx-input-text',
454
- imports: [
455
- SpxDropdownComponent
456
- ],
457
- template: `<div class="relative text-black">
458
- <input
459
- #input
460
- class="font-bold text-lg w-full outline-none"
461
- autocomplete="off"
462
- spellcheck="false"
463
- [class.bg-white]="!this.spxReadonly"
464
- [class.bg-gray-300]="this.spxReadonly"
465
- [class.cursor-not-allowed]="this.spxReadonly"
466
- [class.uppercase]="this.spxCapitalize"
467
- [attr.autocomplete]="this.spxAutocomplete ? this.spxAutocomplete : undefined"
468
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
469
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
470
- [attr.inputMode]="this.spxInputMode ? this.spxInputMode : undefined"
471
- [attr.pattern]="this.spxPattern ? this.spxPattern : undefined"
472
- [attr.name]="this.spxName"
473
- [attr.type]="this.spxType"
474
- [value]="this.value?.description ? this.value?.description : this.value?.value"
475
- (blur)="this.handleBlur()"
476
- (keyUp)="this.handleKeyUp()"
477
- (focus)="this.handleFocus()"
478
- (input)="this.handleDescriptionInput($event)"
479
- />
480
- @if (this.value?.description && this.value?.value && this.value?.description?.valueOf() !== this.value?.value?.valueOf()) {
481
- <span>{{this.value?.value}}</span>
482
- }
483
- @if (this.spxFocused && (this.spxType === 'overlay' || this.spxType === 'overlaynumber')) {
484
- <spx-dropdown
485
- [spxSuggestions]="this.spxSuggestions" (spxSelect)="this.handleSuggestionClick($event)">
486
- </spx-dropdown>
487
- }
488
- </div>`
489
- }]
490
- }], propDecorators: { spxName: [{
491
- type: Input
492
- }], spxAutofocus: [{
493
- type: Input
494
- }], spxAutocomplete: [{
495
- type: Input
496
- }], spxInputMode: [{
497
- type: Input
498
- }], spxPattern: [{
499
- type: Input
500
- }], spxSuggestions: [{
501
- type: Input
502
- }], spxReadonly: [{
503
- type: Input
504
- }], spxValidators: [{
505
- type: Input
506
- }], spxCapitalize: [{
507
- type: Input
508
- }], spxFocused: [{
509
- type: Input
510
- }], spxType: [{
511
- type: Input
512
- }], value: [{
513
- type: Input
514
- }], spxBlurFromChild: [{
515
- type: Output
516
- }], spxChange: [{
517
- type: Output
518
- }], spxFocus: [{
519
- type: Output
520
- }], spxWasInternalUpdate: [{
521
- type: Input
522
- }], inputRef: [{
523
- type: ViewChild,
524
- args: ['input', { static: true }]
525
- }] } });
254
+ args: [{ selector: 'spx-input-text', imports: [
255
+ SpxDropdownComponent,
256
+ ReactiveFormsModule,
257
+ FormsModule
258
+ ], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative text-black\">\r\n <input\r\n #input\r\n class=\"font-bold text-lg w-full outline-none\"\r\n autocomplete=\"off\"\r\n spellcheck=\"false\"\r\n [class.bg-white]=\"!this.spxReadonly()\"\r\n [class.bg-gray-300]=\"this.spxReadonly()\"\r\n [class.cursor-not-allowed]=\"this.spxReadonly()\"\r\n [class.uppercase]=\"this.spxCapitalize()\"\r\n [attr.autocomplete]=\"this.spxAutocomplete()\"\r\n [attr.autofocus]=\"this.spxAutofocus()\"\r\n [attr.disabled]=\"this.spxReadonly()\"\r\n [attr.inputMode]=\"this.spxInputMode()\"\r\n [attr.pattern]=\"this.spxPattern()\"\r\n [attr.name]=\"this.spxName()\"\r\n [attr.type]=\"this.spxType()\"\r\n [ngModel]=\"this.value().description ? this.value().description : this.value().value\"\r\n (ngModelChange)=\"this.handleChange($event)\"\r\n />\r\n\r\n @if (this.value().description && this.value().value && this.value().description?.valueOf() !== this.value().value?.valueOf()) {\r\n <span>{{this.value().value}}</span>\r\n }\r\n @if (this.spxIsFocused() && (this.spxType() === 'overlay' || this.spxType() === 'overlaynumber')) {\r\n <spx-dropdown\r\n [spxSuggestions]=\"this.spxSuggestions()\" (spxSelect)=\"this.handleSuggestionClick($event)\">\r\n </spx-dropdown>\r\n }\r\n</div>" }]
259
+ }] });
526
260
 
527
261
  class SpxInputFloatComponent {
528
262
  constructor() {
529
- this.internalValue = {
263
+ this.internalValue = signal({
530
264
  first: null,
531
265
  second: null,
532
- };
533
- this.spxAutofocus = false;
534
- this.spxReadonly = false;
535
- this.spxFocused = true;
536
- this.spxChange = new EventEmitter();
537
- this.spxFocus = new EventEmitter();
538
- this.spxWasInternalUpdate = false;
539
- this.tick = {};
266
+ });
267
+ this.spxName = input();
268
+ this.spxAutofocus = input(false);
269
+ this.spxElementId = input();
270
+ this.spxReadonly = input(false);
271
+ this.spxValidators = input();
272
+ this.spxStep = input();
273
+ this.value = model.required();
274
+ this.spxWasInternalUpdate = input(false);
275
+ this.selectedInputService = inject(SelectedInputService);
276
+ this.spxIsFocused = signal(false);
277
+ this.firstInputRef = viewChild('firstInputRef');
278
+ this.secondInputRef = viewChild('secondInputRef');
540
279
  }
541
280
  spxSetFocus() {
542
- this.firstInputRef?.nativeElement?.focus();
281
+ this.firstInputRef()?.nativeElement?.focus();
543
282
  }
544
283
  ngOnInit() {
545
- if (this.spxAutofocus) {
546
- this.spxFocus.emit();
284
+ if (this.spxAutofocus()) {
547
285
  this.spxSetFocus();
548
286
  }
549
- this.handleSetValue(this.value);
550
- }
551
- ngOnChanges(changes) {
552
- if (changes['value']) {
553
- this.handleSetValue(changes['value'].currentValue);
554
- }
555
- }
556
- handleFocus() {
557
- this.spxFocus.emit();
287
+ this.selectedInputService.focusedElement$
288
+ .subscribe((focusedId) => {
289
+ if (focusedId === this.spxElementId() && this.spxIsFocused() == false) {
290
+ this.spxIsFocused.set(true); // Update only if focused
291
+ this.spxSetFocus();
292
+ }
293
+ else if (focusedId !== this.spxElementId() && focusedId != null) {
294
+ this.spxIsFocused.set(false);
295
+ }
296
+ });
297
+ this.handleSetValue(this.value());
558
298
  }
559
299
  handleSetValue(newValue) {
560
300
  if (this.isNumeric(newValue?.value)) {
561
- this.internalValue = {
301
+ this.internalValue.set({
562
302
  first: Math.floor(parseFloat(newValue?.value)),
563
303
  second: newValue?.value?.split ? newValue?.value.split('.')[1] : 0,
564
- };
304
+ });
565
305
  }
566
306
  else {
567
- this.internalValue = {
307
+ this.internalValue.set({
568
308
  first: null,
569
309
  second: null,
570
- };
310
+ });
571
311
  }
572
- this.tick = {};
573
312
  }
574
313
  handleInput(value, position) {
575
- this.internalValue = {
576
- first: position === 1 ? value : this.internalValue.first,
577
- second: position === 2 ? value : this.internalValue.second,
578
- };
314
+ this.internalValue.set({
315
+ first: position === 1 ? value : this.internalValue().first,
316
+ second: position === 2 ? value : this.internalValue().second,
317
+ });
579
318
  let result;
580
- if (this.internalValue.first === null && this.internalValue.second === null) {
319
+ if (this.internalValue().first === null && this.internalValue().second === null) {
581
320
  result = null;
582
321
  }
583
322
  else {
584
- result = `${this.internalValue.first ? this.internalValue.first : 0}.${this.internalValue.second ? this.internalValue.second : 0}`;
323
+ result = `${this.internalValue().first ? this.internalValue().first : 0}.${this.internalValue().second ? this.internalValue().second : 0}`;
585
324
  }
586
- this.value = {
325
+ this.value.set({
587
326
  description: result,
588
327
  value: result,
589
- };
590
- this.spxChange.emit(this.value);
328
+ });
329
+ }
330
+ handleClear() {
331
+ this.internalValue().first = null;
332
+ this.internalValue().second = null;
591
333
  }
592
334
  isNumeric(value) {
593
335
  return /^[+-]?\d+(\.\d+)?$/.test(value);
594
336
  }
595
337
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputFloatComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
596
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SpxInputFloatComponent, isStandalone: true, selector: "spx-input-float", inputs: { spxName: "spxName", spxAutofocus: "spxAutofocus", spxReadonly: "spxReadonly", spxValidators: "spxValidators", spxFocused: "spxFocused", spxStep: "spxStep", value: "value", spxWasInternalUpdate: "spxWasInternalUpdate", tick: "tick" }, outputs: { spxChange: "spxChange", spxFocus: "spxFocus" }, viewQueries: [{ propertyName: "firstInputRef", first: true, predicate: ["firstInputRef"], descendants: true, static: true }], usesOnChanges: true, ngImport: i0, template: `<div class="flex items-end">
597
- <input
598
- #firstInputRef
599
- class="spx-input-float__input"
600
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
601
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
602
- [attr.pattern]="'[0-9]*'"
603
- [attr.step]="1"
604
- [attr.type]="'text'"
605
- [class.spx-input-float--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
606
- (focus)="this.handleFocus()"
607
- [ngModel]="this.internalValue?.first ? this.internalValue?.first : undefined"
608
- (ngModelChange)="this.handleInput($event, 1)" />
609
- <span class="text-black font-bold text-2xl mx-4">,</span>
610
- <input
611
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
612
- class="spx-input-float__input"
613
- [class.spx-input-float--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
614
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
615
- (focus)="this.handleFocus()"
616
- [ngModel]="this.internalValue?.second ? this.internalValue?.second : undefined"
617
- (ngModelChange)="this.handleInput($event, 2)"
618
- [attr.step]="1"
619
- [attr.type]="'text'"
620
- [attr.pattern]="'[0-9]*'" />
621
- </div>`, isInline: true, styles: [":host{display:block}.spx-input-float__input{border:1px solid #333333;border-radius:8px;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));flex:1;font-size:20px;font-weight:700;padding:8px;width:100%}.spx-input-float__input:focus{outline:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
338
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.5", type: SpxInputFloatComponent, isStandalone: true, selector: "spx-input-float", inputs: { spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxAutofocus: { classPropertyName: "spxAutofocus", publicName: "spxAutofocus", isSignal: true, isRequired: false, transformFunction: null }, spxElementId: { classPropertyName: "spxElementId", publicName: "spxElementId", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxStep: { classPropertyName: "spxStep", publicName: "spxStep", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, spxWasInternalUpdate: { classPropertyName: "spxWasInternalUpdate", publicName: "spxWasInternalUpdate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "firstInputRef", first: true, predicate: ["firstInputRef"], descendants: true, isSignal: true }, { propertyName: "secondInputRef", first: true, predicate: ["secondInputRef"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"flex items-end\">\r\n <input\r\n #firstInputRef\r\n class=\"spx-input-float__input\"\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.pattern]=\"'[0-9]*'\"\r\n [attr.step]=\"1\"\r\n [attr.type]=\"'text'\"\r\n [class.spx-input-float--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [ngModel]=\"this.internalValue().first ? this.internalValue().first : undefined\"\r\n (ngModelChange)=\"this.handleInput($event, 1)\" />\r\n <span class=\"text-black font-bold text-2xl mx-4\">,</span>\r\n <input #secondInputRef\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n class=\"spx-input-float__input\"\r\n [class.spx-input-float--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [ngModel]=\"this.internalValue().second ? this.internalValue().second : undefined\"\r\n (ngModelChange)=\"this.handleInput($event, 2)\"\r\n [attr.step]=\"1\"\r\n [attr.type]=\"'text'\"\r\n [attr.pattern]=\"'[0-9]*'\" />\r\n</div>", styles: [":host{display:block}.spx-input-float__input{border:1px solid #333333;border-radius:8px;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));flex:1;font-size:20px;font-weight:700;padding:8px;width:100%}.spx-input-float__input:focus{outline:none}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
622
339
  }
623
340
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputFloatComponent, decorators: [{
624
341
  type: Component,
625
342
  args: [{ selector: 'spx-input-float', imports: [
626
343
  FormsModule,
627
- ], template: `<div class="flex items-end">
628
- <input
629
- #firstInputRef
630
- class="spx-input-float__input"
631
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
632
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
633
- [attr.pattern]="'[0-9]*'"
634
- [attr.step]="1"
635
- [attr.type]="'text'"
636
- [class.spx-input-float--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
637
- (focus)="this.handleFocus()"
638
- [ngModel]="this.internalValue?.first ? this.internalValue?.first : undefined"
639
- (ngModelChange)="this.handleInput($event, 1)" />
640
- <span class="text-black font-bold text-2xl mx-4">,</span>
641
- <input
642
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
643
- class="spx-input-float__input"
644
- [class.spx-input-float--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
645
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
646
- (focus)="this.handleFocus()"
647
- [ngModel]="this.internalValue?.second ? this.internalValue?.second : undefined"
648
- (ngModelChange)="this.handleInput($event, 2)"
649
- [attr.step]="1"
650
- [attr.type]="'text'"
651
- [attr.pattern]="'[0-9]*'" />
652
- </div>`, styles: [":host{display:block}.spx-input-float__input{border:1px solid #333333;border-radius:8px;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));flex:1;font-size:20px;font-weight:700;padding:8px;width:100%}.spx-input-float__input:focus{outline:none}\n"] }]
653
- }], propDecorators: { spxName: [{
654
- type: Input
655
- }], spxAutofocus: [{
656
- type: Input
657
- }], spxReadonly: [{
658
- type: Input
659
- }], spxValidators: [{
660
- type: Input
661
- }], spxFocused: [{
662
- type: Input
663
- }], spxStep: [{
664
- type: Input
665
- }], value: [{
666
- type: Input
667
- }], spxChange: [{
668
- type: Output
669
- }], spxFocus: [{
670
- type: Output
671
- }], spxWasInternalUpdate: [{
672
- type: Input
673
- }], tick: [{
674
- type: Input
675
- }], firstInputRef: [{
676
- type: ViewChild,
677
- args: ['firstInputRef', { static: true }]
678
- }] } });
344
+ ], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"flex items-end\">\r\n <input\r\n #firstInputRef\r\n class=\"spx-input-float__input\"\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.pattern]=\"'[0-9]*'\"\r\n [attr.step]=\"1\"\r\n [attr.type]=\"'text'\"\r\n [class.spx-input-float--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [ngModel]=\"this.internalValue().first ? this.internalValue().first : undefined\"\r\n (ngModelChange)=\"this.handleInput($event, 1)\" />\r\n <span class=\"text-black font-bold text-2xl mx-4\">,</span>\r\n <input #secondInputRef\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n class=\"spx-input-float__input\"\r\n [class.spx-input-float--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [ngModel]=\"this.internalValue().second ? this.internalValue().second : undefined\"\r\n (ngModelChange)=\"this.handleInput($event, 2)\"\r\n [attr.step]=\"1\"\r\n [attr.type]=\"'text'\"\r\n [attr.pattern]=\"'[0-9]*'\" />\r\n</div>", styles: [":host{display:block}.spx-input-float__input{border:1px solid #333333;border-radius:8px;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));flex:1;font-size:20px;font-weight:700;padding:8px;width:100%}.spx-input-float__input:focus{outline:none}\n"] }]
345
+ }] });
679
346
 
680
347
  class SpxInputNumberComponent {
681
348
  constructor() {
682
- this.spxAutofocus = false;
683
- this.spxReadonly = false;
684
- this.spxFocused = true;
685
- this.spxChange = new EventEmitter();
686
- this.spxFocus = new EventEmitter();
687
- this.spxWasInternalUpdate = false;
349
+ this.spxName = input();
350
+ this.spxAutofocus = input(false);
351
+ this.spxInputMode = input();
352
+ this.spxReadonly = input(false);
353
+ this.spxValidators = input();
354
+ this.spxFocused = input(true);
355
+ this.spxStep = input();
356
+ this.value = model.required();
357
+ this.inputRef = viewChild.required('input');
358
+ this.spxElementId = input();
359
+ this.selectedInputService = inject(SelectedInputService);
360
+ }
361
+ ngOnInit() {
362
+ // Filter updates based on focus state
363
+ this.selectedInputService.focusedElement$
364
+ .pipe(filter((focusedId) => focusedId === this.spxElementId()))
365
+ .subscribe(() => {
366
+ this.spxSetFocus();
367
+ });
688
368
  }
689
369
  spxSetFocus() {
690
- this.inputRef?.nativeElement?.focus();
370
+ this.inputRef().nativeElement?.focus();
371
+ }
372
+ handleChange($event) {
373
+ this.value.set({ ...this.value(), value: $event });
691
374
  }
692
375
  componentDidLoad() {
693
- if (this.spxAutofocus) {
694
- this.spxFocus.emit();
376
+ if (this.spxAutofocus()) {
695
377
  this.spxSetFocus();
696
378
  }
697
379
  }
698
- handleFocus() {
699
- this.spxFocus.emit();
700
- }
701
- handleInput(event) {
702
- this.value = {
703
- description: event.target ? event.target.value : null,
704
- value: event.target ? event.target.value : null,
705
- };
706
- this.spxChange.emit(this.value);
707
- }
708
380
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputNumberComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
709
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SpxInputNumberComponent, isStandalone: true, selector: "spx-input-number", inputs: { spxName: "spxName", spxAutofocus: "spxAutofocus", spxInputMode: "spxInputMode", spxReadonly: "spxReadonly", spxValidators: "spxValidators", spxFocused: "spxFocused", spxStep: "spxStep", value: "value" }, outputs: { spxChange: "spxChange", spxFocus: "spxFocus" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, static: true }], ngImport: i0, template: `<div class="spx-input-number__controls">
710
- <input
711
- #input
712
- class="spx-input-number__input"
713
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
714
- [class.spx-input-number--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
715
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
716
- [attr.inputMode]="this.spxInputMode ? this.spxInputMode : undefined"
717
- [attr.value]="this.value?.value ? this.value?.value : undefined"
718
- [attr.step]="this.spxStep ? this.spxStep : undefined"
719
- [attr.type]="'number'"
720
- (focus)="this.handleFocus()"
721
- (input)="this.handleInput($event)" />
722
- </div>`, isInline: true, styles: [":host{display:block}.spx-input-number__input{border:0;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));font-size:20px;font-weight:700;margin-right:10px;padding:0;width:100%}.spx-input-number__input:focus{outline:none}.spx-input-number__value{color:#0009;font-size:14px}\n"] }); }
381
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.5", type: SpxInputNumberComponent, isStandalone: true, selector: "spx-input-number", inputs: { spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxAutofocus: { classPropertyName: "spxAutofocus", publicName: "spxAutofocus", isSignal: true, isRequired: false, transformFunction: null }, spxInputMode: { classPropertyName: "spxInputMode", publicName: "spxInputMode", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxFocused: { classPropertyName: "spxFocused", publicName: "spxFocused", isSignal: true, isRequired: false, transformFunction: null }, spxStep: { classPropertyName: "spxStep", publicName: "spxStep", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, spxElementId: { classPropertyName: "spxElementId", publicName: "spxElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"spx-input-number__controls\">\r\n <input\r\n #input\r\n class=\"spx-input-number__input\"\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n [class.spx-input-number--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.inputMode]=\"this.spxInputMode() ? this.spxInputMode() : undefined\"\r\n [attr.step]=\"this.spxStep() ? this.spxStep() : undefined\"\r\n [attr.type]=\"'number'\"\r\n [ngModel]=\"this.value().value\"\r\n (ngModelChange)=\"this.handleChange($event)\" />\r\n</div> ", styles: [":host{display:block}.spx-input-number__input{border:0;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));font-size:20px;font-weight:700;margin-right:10px;padding:0;width:100%}.spx-input-number__input:focus{outline:none}.spx-input-number__value{color:#0009;font-size:14px}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
723
382
  }
724
383
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputNumberComponent, decorators: [{
725
384
  type: Component,
726
- args: [{ selector: 'spx-input-number', imports: [], template: `<div class="spx-input-number__controls">
727
- <input
728
- #input
729
- class="spx-input-number__input"
730
- [attr.autofocus]="this.spxAutofocus ? this.spxAutofocus : undefined"
731
- [class.spx-input-number--readonly]="this.spxReadonly ? this.spxReadonly : undefined"
732
- [attr.disabled]="this.spxReadonly ? this.spxReadonly : undefined"
733
- [attr.inputMode]="this.spxInputMode ? this.spxInputMode : undefined"
734
- [attr.value]="this.value?.value ? this.value?.value : undefined"
735
- [attr.step]="this.spxStep ? this.spxStep : undefined"
736
- [attr.type]="'number'"
737
- (focus)="this.handleFocus()"
738
- (input)="this.handleInput($event)" />
739
- </div>`, styles: [":host{display:block}.spx-input-number__input{border:0;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));font-size:20px;font-weight:700;margin-right:10px;padding:0;width:100%}.spx-input-number__input:focus{outline:none}.spx-input-number__value{color:#0009;font-size:14px}\n"] }]
740
- }], propDecorators: { spxName: [{
741
- type: Input
742
- }], spxAutofocus: [{
743
- type: Input
744
- }], spxInputMode: [{
745
- type: Input
746
- }], spxReadonly: [{
747
- type: Input
748
- }], spxValidators: [{
749
- type: Input
750
- }], spxFocused: [{
751
- type: Input
752
- }], spxStep: [{
753
- type: Input
754
- }], value: [{
755
- type: Input
756
- }], spxChange: [{
757
- type: Output
758
- }], spxFocus: [{
759
- type: Output
760
- }], inputRef: [{
761
- type: ViewChild,
762
- args: ['input', { static: true }]
763
- }] } });
385
+ args: [{ selector: 'spx-input-number', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, imports: [FormsModule], template: "<div class=\"spx-input-number__controls\">\r\n <input\r\n #input\r\n class=\"spx-input-number__input\"\r\n [attr.autofocus]=\"this.spxAutofocus() ? this.spxAutofocus() : undefined\"\r\n [class.spx-input-number--readonly]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.disabled]=\"this.spxReadonly() ? this.spxReadonly() : undefined\"\r\n [attr.inputMode]=\"this.spxInputMode() ? this.spxInputMode() : undefined\"\r\n [attr.step]=\"this.spxStep() ? this.spxStep() : undefined\"\r\n [attr.type]=\"'number'\"\r\n [ngModel]=\"this.value().value\"\r\n (ngModelChange)=\"this.handleChange($event)\" />\r\n</div> ", styles: [":host{display:block}.spx-input-number__input{border:0;background-color:transparent;box-sizing:border-box;color:var(--spx-input--color, rgba(0, 0, 0, .9));font-size:20px;font-weight:700;margin-right:10px;padding:0;width:100%}.spx-input-number__input:focus{outline:none}.spx-input-number__value{color:#0009;font-size:14px}\n"] }]
386
+ }] });
764
387
 
765
388
  class SpxInputRadioComponent {
766
389
  constructor() {
767
- this.cachedSuggestions = [];
768
- this.focusPosition = 0;
769
- this.spxFocused = false;
770
- this.spxShowLabel = true;
771
- this.spxReadonly = false;
772
- this.spxSuggestions = [];
773
- this.spxChange = new EventEmitter();
774
- this.spxFocus = new EventEmitter();
775
- }
776
- spxFocusIn() {
777
- this.listenToKeys();
778
- this.determineFocusPosition();
390
+ this.cachedSuggestions = signal([]);
391
+ this.focusPosition = signal(0);
392
+ this.spxName = input();
393
+ this.spxValidators = input();
394
+ this.spxShowLabel = input(true);
395
+ this.spxReadonly = input(false);
396
+ this.spxSuggestions = input([]);
397
+ this.value = model.required();
398
+ this.selectedInputService = inject(SelectedInputService);
399
+ this.spxElementId = input();
400
+ this.spxIsFocused = signal(false);
779
401
  }
780
- spxFocusOut() {
781
- this.subscriptionKeyDown?.unsubscribe();
782
- this.subscriptionKeyUp?.unsubscribe();
402
+ ngOnInit() {
403
+ this.selectedInputService.focusedElement$
404
+ .subscribe((focusedId) => {
405
+ if (focusedId === this.spxElementId() && this.spxIsFocused() == false) {
406
+ this.spxIsFocused.set(true); // Update only if focused
407
+ this.listenToKeys();
408
+ }
409
+ else if (focusedId !== this.spxElementId() && this.spxIsFocused() == true) {
410
+ this.spxIsFocused.set(false);
411
+ this.subscriptionKeyDown?.unsubscribe();
412
+ this.subscriptionKeyUp?.unsubscribe();
413
+ }
414
+ this.determineFocusPosition();
415
+ });
783
416
  }
784
417
  ngOnChanges(changes) {
785
418
  if ((changes['spxSuggestions'] && JSON.stringify(changes['spxSuggestions']?.previousValue) !== JSON.stringify(changes['spxSuggestions']?.currentValue))) {
786
- this.cachedSuggestions = changes['spxSuggestions']?.currentValue ?? [];
419
+ this.cachedSuggestions.set(changes['spxSuggestions']?.currentValue ?? []);
787
420
  }
788
421
  }
789
- handleSuggestionClick(event, valuePair) {
790
- if (this.spxReadonly) {
422
+ handleSuggestionClick(valuePair) {
423
+ if (this.spxReadonly()) {
791
424
  console.log('spxInputRadio: clicked, but readonly');
792
425
  }
793
426
  else {
794
427
  console.log('spxInputRadio: clicked');
795
428
  this.select(valuePair);
796
429
  }
430
+ this.determineFocusPosition();
797
431
  }
798
432
  determineFocusPosition() {
799
- if (this.value && this.spxSuggestions?.length) {
800
- const index = this.spxSuggestions.findIndex(valuePair => valuePairToValue(valuePair) === valuePairToValue(this.value));
801
- this.focusPosition = index >= 0 ? index : 0;
433
+ const spxSuggestions = this.spxSuggestions();
434
+ if (this.value() && spxSuggestions?.length) {
435
+ const index = spxSuggestions.findIndex(valuePair => valuePairToValue(valuePair) === valuePairToValue(this.value()));
436
+ this.focusPosition.set(index >= 0 ? index : 0);
802
437
  }
803
438
  else {
804
- this.focusPosition = 0;
439
+ this.focusPosition.set(0);
805
440
  }
806
441
  }
807
442
  select(valuePair) {
808
- this.focusPosition = 0;
809
- this.value = valuePair;
810
- this.spxChange.emit(valuePair);
443
+ this.value.set(valuePair);
811
444
  }
812
445
  listenToKeys() {
813
446
  this.subscriptionKeyUp = fromEvent(window, 'keyup').subscribe((event) => {
814
- if ((event.key === 'ArrowUp' || event.key === 'ArrowLeft') && this.focusPosition > 0) {
815
- this.focusPosition = this.focusPosition - 1;
816
- this.select(this.spxSuggestions.at(this.focusPosition));
447
+ if ((event.key === 'ArrowUp' || event.key === 'ArrowLeft') && this.focusPosition() > 0) {
448
+ this.focusPosition.update((position) => position - 1);
449
+ this.select(this.spxSuggestions().at(this.focusPosition()));
817
450
  event.preventDefault();
818
451
  }
819
- if ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && this.focusPosition < this.spxSuggestions.length - 1) {
820
- this.focusPosition = this.focusPosition + 1;
821
- this.select(this.spxSuggestions.at(this.focusPosition));
452
+ if ((event.key === 'ArrowDown' || event.key === 'ArrowRight') && this.focusPosition() < this.spxSuggestions().length - 1) {
453
+ this.focusPosition.update((position) => position + 1);
454
+ this.select(this.spxSuggestions().at(this.focusPosition()));
822
455
  event.preventDefault();
823
456
  }
824
457
  });
@@ -832,141 +465,41 @@ class SpxInputRadioComponent {
832
465
  });
833
466
  }
834
467
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputRadioComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
835
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputRadioComponent, isStandalone: true, selector: "spx-input-radio", inputs: { spxName: "spxName", spxValidators: "spxValidators", spxFocused: "spxFocused", spxShowLabel: "spxShowLabel", spxReadonly: "spxReadonly", spxSuggestions: "spxSuggestions", value: "value" }, outputs: { spxChange: "spxChange", spxFocus: "spxFocus" }, usesOnChanges: true, ngImport: i0, template: `<div class="grid grid-cols-2 gap-2" [class.mt-3]="this.spxShowLabel">
836
- @for (valuePair of this.cachedSuggestions; track valuePair; let i = $index) {
837
- <spx-suggestion
838
- [spxDisabled]="this.spxReadonly"
839
- [spxFocused]="this.spxFocused && i === this.focusPosition"
840
- [spxSelected]="this.value?.value === valuePair?.value"
841
- [spxTabbable]="this.focusPosition === i"
842
- (click)="this.handleSuggestionClick($event, valuePair)">
843
- {{valuePair?.description}}
844
- </spx-suggestion>
845
- }
846
- </div>`, isInline: true, dependencies: [{ kind: "component", type: SpxSuggestionComponent, selector: "spx-suggestion", inputs: ["spxDisabled", "spxFocused", "spxSelected", "spxTabbable"] }] }); }
468
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputRadioComponent, isStandalone: true, selector: "spx-input-radio", inputs: { spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxShowLabel: { classPropertyName: "spxShowLabel", publicName: "spxShowLabel", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null }, spxElementId: { classPropertyName: "spxElementId", publicName: "spxElementId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, usesOnChanges: true, ngImport: i0, template: "<div class=\"grid grid-cols-2 gap-2\" [class.mt-3]=\"this.spxShowLabel()\">\r\n @for (valuePair of this.cachedSuggestions(); track valuePair; let i = $index) {\r\n <spx-suggestion\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSelected]=\"this.value().value === valuePair?.value\"\r\n [spxTabbable]=\"this.focusPosition() === i\"\r\n [spxFocused]=\"(this.focusPosition() === i && this.spxIsFocused())\"\r\n (click)=\"this.handleSuggestionClick(valuePair)\">\r\n {{valuePair?.description}}\r\n </spx-suggestion>\r\n }\r\n</div>", dependencies: [{ kind: "component", type: SpxSuggestionComponent, selector: "spx-suggestion", inputs: ["spxDisabled", "spxFocused", "spxSelected", "spxTabbable"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
847
469
  }
848
470
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputRadioComponent, decorators: [{
849
471
  type: Component,
850
- args: [{
851
- selector: 'spx-input-radio',
852
- imports: [
472
+ args: [{ selector: 'spx-input-radio', standalone: true, imports: [
853
473
  SpxSuggestionComponent
854
- ],
855
- template: `<div class="grid grid-cols-2 gap-2" [class.mt-3]="this.spxShowLabel">
856
- @for (valuePair of this.cachedSuggestions; track valuePair; let i = $index) {
857
- <spx-suggestion
858
- [spxDisabled]="this.spxReadonly"
859
- [spxFocused]="this.spxFocused && i === this.focusPosition"
860
- [spxSelected]="this.value?.value === valuePair?.value"
861
- [spxTabbable]="this.focusPosition === i"
862
- (click)="this.handleSuggestionClick($event, valuePair)">
863
- {{valuePair?.description}}
864
- </spx-suggestion>
865
- }
866
- </div>`
867
- }]
868
- }], propDecorators: { spxName: [{
869
- type: Input
870
- }], spxValidators: [{
871
- type: Input
872
- }], spxFocused: [{
873
- type: Input
874
- }], spxShowLabel: [{
875
- type: Input
876
- }], spxReadonly: [{
877
- type: Input
878
- }], spxSuggestions: [{
879
- type: Input
880
- }], value: [{
881
- type: Input
882
- }], spxChange: [{
883
- type: Output
884
- }], spxFocus: [{
885
- type: Output
886
- }] } });
887
-
888
- var SpxInputTypeEnum;
889
- (function (SpxInputTypeEnum) {
890
- SpxInputTypeEnum["autocomplete"] = "autocomplete";
891
- SpxInputTypeEnum["button"] = "button";
892
- SpxInputTypeEnum["date"] = "date";
893
- SpxInputTypeEnum["float"] = "float";
894
- SpxInputTypeEnum["hidden"] = "hidden";
895
- SpxInputTypeEnum["overlay"] = "overlay";
896
- SpxInputTypeEnum["overlayNumber"] = "overlaynumber";
897
- SpxInputTypeEnum["radio"] = "radio";
898
- SpxInputTypeEnum["number"] = "number";
899
- SpxInputTypeEnum["password"] = "password";
900
- SpxInputTypeEnum["text"] = "text";
901
- SpxInputTypeEnum["textNumericKeyboard"] = "textNumericKeyboard";
902
- SpxInputTypeEnum["time"] = "time";
903
- })(SpxInputTypeEnum || (SpxInputTypeEnum = {}));
474
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"grid grid-cols-2 gap-2\" [class.mt-3]=\"this.spxShowLabel()\">\r\n @for (valuePair of this.cachedSuggestions(); track valuePair; let i = $index) {\r\n <spx-suggestion\r\n [spxDisabled]=\"this.spxReadonly()\"\r\n [spxSelected]=\"this.value().value === valuePair?.value\"\r\n [spxTabbable]=\"this.focusPosition() === i\"\r\n [spxFocused]=\"(this.focusPosition() === i && this.spxIsFocused())\"\r\n (click)=\"this.handleSuggestionClick(valuePair)\">\r\n {{valuePair?.description}}\r\n </spx-suggestion>\r\n }\r\n</div>" }]
475
+ }] });
904
476
 
905
477
  class SpxInputTimeModalComponent {
906
478
  constructor(modalController) {
907
479
  this.modalController = modalController;
908
- this.change = new EventEmitter();
480
+ this.view = input.required();
481
+ this.value = input.required();
482
+ this.change = output();
909
483
  this.faXmark = faXmark;
910
- this.hourOptions = Array.from({ length: 24 }, (_, i) => i); // 0 to 23
911
- this.minuteOptions = Array.from({ length: 12 }, (_, i) => i * 5); // Minutes in incrementen van 5
484
+ this.hourOptions = signal(Array.from({ length: 24 }, (_, i) => i)); // 0 to 23
485
+ this.minuteOptions = signal(Array.from({ length: 12 }, (_, i) => i * 5)); // Minutes in incrementen van 5
912
486
  this.typeError = SpxSeverityEnum.error;
913
- this.hourOptions.push(this.hourOptions.shift());
914
- this.minuteOptions.push(this.minuteOptions.shift());
487
+ this.hourOptions().push(this.hourOptions().shift());
488
+ this.minuteOptions().push(this.minuteOptions().shift());
915
489
  }
916
490
  closeDialog() {
917
491
  this.modalController.dismiss();
918
492
  }
919
493
  onChange(value) {
920
494
  this.change.emit(value);
921
- console.log(value);
922
495
  this.modalController.dismiss(value);
923
496
  }
924
497
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTimeModalComponent, deps: [{ token: i1$2.ModalController }], target: i0.ɵɵFactoryTarget.Component }); }
925
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputTimeModalComponent, isStandalone: true, selector: "spx-input-time-modal", inputs: { view: "view", value: "value" }, outputs: { change: "change" }, ngImport: i0, template: `<ion-header>
926
- <ion-toolbar>
927
- <ion-title>Select {{view}}</ion-title>
928
- <ion-buttons slot="end">
929
- <spx-button [spxSeverity]="typeError" (spxClick)="closeDialog()">
930
- <fa-icon [icon]="faXmark"></fa-icon>
931
- </spx-button>
932
- </ion-buttons>
933
- </ion-toolbar>
934
- </ion-header>
935
- <ion-content class="ion-padding bg-white">
936
- <!-- Uren -->
937
- <div class="custom-bg grid grid-cols-1 gap-3">
938
- @if (view === 'hours') {
939
- <div class="flex-wrap gap-2">
940
- <div class="grid grid-cols-3 md:grid-cols-4 gap-3">
941
- @for (hour of hourOptions; track hour) {
942
- <div class="text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-full truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300" [class.selected]="value === hour" (click)="onChange(hour)">
943
- {{ hour }}
944
- </div>
945
- }
946
- </div>
947
- </div>
948
- }
949
- <!-- Minuten -->
950
- @if (view === 'minutes') {
951
- <div class="grid grid-cols-1 gap-3">
952
- <div class="grid grid-cols-4 md:grid-cols-5 gap-3">
953
- @for (minute of minuteOptions; track minute) {
954
- <div class="text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-ful truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300" [class.selected]="value === minute" (click)="onChange(minute)">
955
- {{ minute }}
956
- </div>
957
- }
958
- </div>
959
- </div>
960
- }
961
- </div>
962
- </ion-content>
963
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }] }); }
498
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputTimeModalComponent, isStandalone: true, selector: "spx-input-time-modal", inputs: { view: { classPropertyName: "view", publicName: "view", isSignal: true, isRequired: true, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { change: "change" }, ngImport: i0, template: "<ion-header>\r\n <ion-toolbar>\r\n <ion-title>Select {{view()}}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <spx-button [spxSeverity]=\"typeError\" (spxClick)=\"closeDialog()\">\r\n <fa-icon [icon]=\"faXmark\"></fa-icon>\r\n </spx-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n</ion-header>\r\n<ion-content class=\"ion-padding bg-white\">\r\n <!-- Uren -->\r\n <div class=\"custom-bg grid grid-cols-1 gap-3\">\r\n @if (view() === 'hours') {\r\n <div class=\"flex-wrap gap-2\">\r\n <div class=\"grid grid-cols-3 md:grid-cols-4 gap-3\">\r\n @for (hour of hourOptions(); track hour) {\r\n <div class=\"text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-full truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300\" [class.selected]=\"value() === hour\" (click)=\"onChange(hour)\">\r\n {{ hour }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Minuten -->\r\n @if (view() === 'minutes') {\r\n <div class=\"grid grid-cols-1 gap-3\">\r\n <div class=\"grid grid-cols-4 md:grid-cols-5 gap-3\">\r\n @for (minute of minuteOptions(); track minute) {\r\n <div class=\"text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-ful truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300\" [class.selected]=\"value() === minute\" (click)=\"onChange(minute)\">\r\n {{ minute }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</ion-content>", dependencies: [{ kind: "ngmodule", type: FontAwesomeModule }, { kind: "component", type: i1.FaIconComponent, selector: "fa-icon", inputs: ["icon", "title", "animation", "mask", "flip", "size", "pull", "border", "inverse", "symbol", "rotate", "fixedWidth", "transform", "a11yRole"] }, { kind: "component", type: IonButtons, selector: "ion-buttons", inputs: ["collapse"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: SpxButtonComponent, selector: "spx-button", inputs: ["spxDisabled", "spxClass", "spxClassObject", "spxForm", "spxFullHeight", "spxFullWidth", "spxSeverity", "spxSize", "spxTabIndex", "spxType"], outputs: ["spxClick"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
964
499
  }
965
500
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTimeModalComponent, decorators: [{
966
501
  type: Component,
967
- args: [{
968
- selector: 'spx-input-time-modal',
969
- imports: [
502
+ args: [{ selector: 'spx-input-time-modal', imports: [
970
503
  FontAwesomeModule,
971
504
  IonButtons,
972
505
  IonContent,
@@ -974,134 +507,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
974
507
  IonTitle,
975
508
  IonToolbar,
976
509
  SpxButtonComponent,
977
- ],
978
- template: `<ion-header>
979
- <ion-toolbar>
980
- <ion-title>Select {{view}}</ion-title>
981
- <ion-buttons slot="end">
982
- <spx-button [spxSeverity]="typeError" (spxClick)="closeDialog()">
983
- <fa-icon [icon]="faXmark"></fa-icon>
984
- </spx-button>
985
- </ion-buttons>
986
- </ion-toolbar>
987
- </ion-header>
988
- <ion-content class="ion-padding bg-white">
989
- <!-- Uren -->
990
- <div class="custom-bg grid grid-cols-1 gap-3">
991
- @if (view === 'hours') {
992
- <div class="flex-wrap gap-2">
993
- <div class="grid grid-cols-3 md:grid-cols-4 gap-3">
994
- @for (hour of hourOptions; track hour) {
995
- <div class="text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-full truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300" [class.selected]="value === hour" (click)="onChange(hour)">
996
- {{ hour }}
997
- </div>
998
- }
999
- </div>
1000
- </div>
1001
- }
1002
- <!-- Minuten -->
1003
- @if (view === 'minutes') {
1004
- <div class="grid grid-cols-1 gap-3">
1005
- <div class="grid grid-cols-4 md:grid-cols-5 gap-3">
1006
- @for (minute of minuteOptions; track minute) {
1007
- <div class="text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-ful truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300" [class.selected]="value === minute" (click)="onChange(minute)">
1008
- {{ minute }}
1009
- </div>
1010
- }
1011
- </div>
1012
- </div>
1013
- }
1014
- </div>
1015
- </ion-content>
1016
- `
1017
- }]
1018
- }], ctorParameters: () => [{ type: i1$2.ModalController }], propDecorators: { view: [{
1019
- type: Input
1020
- }], value: [{
1021
- type: Input
1022
- }], change: [{
1023
- type: Output
1024
- }] } });
510
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ion-header>\r\n <ion-toolbar>\r\n <ion-title>Select {{view()}}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <spx-button [spxSeverity]=\"typeError\" (spxClick)=\"closeDialog()\">\r\n <fa-icon [icon]=\"faXmark\"></fa-icon>\r\n </spx-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n</ion-header>\r\n<ion-content class=\"ion-padding bg-white\">\r\n <!-- Uren -->\r\n <div class=\"custom-bg grid grid-cols-1 gap-3\">\r\n @if (view() === 'hours') {\r\n <div class=\"flex-wrap gap-2\">\r\n <div class=\"grid grid-cols-3 md:grid-cols-4 gap-3\">\r\n @for (hour of hourOptions(); track hour) {\r\n <div class=\"text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-full truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300\" [class.selected]=\"value() === hour\" (click)=\"onChange(hour)\">\r\n {{ hour }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n <!-- Minuten -->\r\n @if (view() === 'minutes') {\r\n <div class=\"grid grid-cols-1 gap-3\">\r\n <div class=\"grid grid-cols-4 md:grid-cols-5 gap-3\">\r\n @for (minute of minuteOptions(); track minute) {\r\n <div class=\"text-center font-bold custom-square rounded text-gray-900 text-lg p-3 w-ful truncate outline-none bg-sky-100 focus:ring-sky-300 hover:bg-sky-300 active:bg-sky-300\" [class.selected]=\"value() === minute\" (click)=\"onChange(minute)\">\r\n {{ minute }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n</ion-content>" }]
511
+ }], ctorParameters: () => [{ type: i1$2.ModalController }] });
1025
512
 
1026
513
  class SpxInputTimeComponent {
1027
- get formattedHour() {
1028
- return this.selectedHour !== null && this.selectedHour < 10 ? `0${this.selectedHour}` : this.selectedHour;
1029
- }
1030
- get formattedMinute() {
1031
- return this.selectedMinute !== null && this.selectedMinute < 10 ? `0${this.selectedMinute}` : this.selectedMinute;
1032
- }
1033
- get hour() { return this.value?.value ? DateTime.fromISO(this.value.value).hour : null; }
1034
- get minute() { return this.value?.value ? DateTime.fromISO(this.value.value).minute : null; }
1035
514
  constructor(modalController) {
1036
515
  this.modalController = modalController;
1037
- this.spxAutofocus = false;
1038
- this.spxSuggestions = [];
1039
- this.spxReadonly = false;
1040
- this.spxCapitalize = false;
1041
- this.spxFocused = true;
1042
- this.spxBlurFromChild = new EventEmitter();
1043
- this.spxChange = new EventEmitter();
1044
- this.spxFocus = new EventEmitter();
1045
- this.spxWasInternalUpdate = false;
516
+ this.spxName = input();
517
+ this.spxAutofocus = input(false);
518
+ this.spxInputMode = input();
519
+ this.spxPattern = input();
520
+ this.spxSuggestions = input([]);
521
+ this.spxReadonly = input(false);
522
+ this.spxValidators = input();
523
+ this.spxCapitalize = input(false);
524
+ this.value = model.required();
525
+ this.inputRef = viewChild.required('input');
1046
526
  this.severitySuccess = SpxSeverityEnum.success;
1047
- this.hourOptions = Array.from({ length: 24 }, (_, i) => i).unshift(); // 0 to 23
1048
- this.minuteOptions = Array.from({ length: 12 }, (_, i) => i * 5).unshift(); // Minutes in incrementen van 5
1049
- this.selectedHour = null;
1050
- this.selectedMinute = null;
527
+ this.selectedHour = signal(null);
528
+ this.selectedMinute = signal(null);
529
+ this.formattedHour = computed(() => this.selectedHour() !== null && this.selectedHour() < 10 ? `0${this.selectedHour()}` : this.selectedHour());
530
+ this.formattedMinute = computed(() => this.selectedMinute() !== null && this.selectedMinute() < 10 ? `0${this.selectedMinute()}` : this.selectedMinute());
531
+ this.hour = computed(() => this.value()?.value ? DateTime.fromISO(this.value().value).hour : null);
532
+ this.minute = computed(() => this.value()?.value ? DateTime.fromISO(this.value().value).minute : null);
533
+ }
534
+ ngOnInit() {
535
+ this.componentDidLoad();
1051
536
  }
1052
537
  spxSetFocus() {
1053
- this.inputRef?.nativeElement?.focus();
538
+ this.inputRef().nativeElement?.focus();
1054
539
  }
1055
540
  componentDidLoad() {
1056
- if (this.spxAutofocus) {
1057
- this.spxFocus.emit();
541
+ if (this.spxAutofocus()) {
1058
542
  this.spxSetFocus();
1059
543
  }
1060
544
  }
1061
- handleBlur() {
1062
- this.spxBlurFromChild.emit();
1063
- }
1064
- handleFocus() {
1065
- this.spxFocus.emit();
1066
- }
1067
545
  handleDescriptionInput(event) {
1068
- this.value = {
546
+ this.value.set({
1069
547
  description: event.target ? event.target.value : null,
1070
548
  value: event.target ? event.target.value : null,
1071
- };
1072
- this.spxChange.emit(this.value);
549
+ });
1073
550
  }
1074
551
  handleSuggestionClick(value) {
1075
- if (!this.spxReadonly) {
1076
- this.value = value;
1077
- this.spxChange.emit(this.value);
1078
- this.spxFocused = false;
552
+ if (!this.spxReadonly()) {
553
+ this.value.set(value);
1079
554
  }
1080
555
  }
1081
- handleKeyUp() {
1082
- this.spxFocused = true;
1083
- }
1084
556
  async openDialog(view) {
557
+ const value = this.value();
1085
558
  const modal = await this.modalController.create({
1086
559
  component: SpxInputTimeModalComponent,
1087
560
  componentProps: {
1088
- value: this.value?.value ?
1089
- (view === 'hours' ? DateTime.fromISO(this.value.value).hour : DateTime.fromISO(this.value.value).minute) : undefined,
561
+ value: value?.value ?
562
+ (view === 'hours' ? DateTime.fromISO(value.value).hour : DateTime.fromISO(value.value).minute) : undefined,
1090
563
  view,
1091
564
  },
1092
565
  });
1093
566
  modal.onDidDismiss().then((data) => {
1094
- // this.appStore.dispatch(infArticleActions.reset({}));
1095
567
  if (view === 'hours') {
1096
- // console.log('hours');
1097
- // console.log(data);
1098
568
  this.selectedHour = data.data;
1099
569
  this.openDialog('minutes');
1100
570
  this.updateValue();
1101
571
  }
1102
572
  else if (view === 'minutes') {
1103
- // console.log('minutes');
1104
- // console.log(data);
1105
573
  this.selectedMinute = data.data;
1106
574
  this.updateValue();
1107
575
  }
@@ -1109,69 +577,23 @@ class SpxInputTimeComponent {
1109
577
  await modal.present();
1110
578
  }
1111
579
  updateValue() {
1112
- if (this.selectedHour !== null && this.selectedMinute !== null) {
1113
- const formattedHour = this.selectedHour < 10 ? `0${this.selectedHour}` : this.selectedHour;
1114
- const formattedMinute = this.selectedMinute < 10 ? `0${this.selectedMinute}` : this.selectedMinute;
580
+ if (this.selectedHour() !== null && this.selectedMinute() !== null) {
581
+ const formattedHour = this.selectedHour() < 10 ? `0${this.selectedHour()}` : this.selectedHour();
582
+ const formattedMinute = this.selectedMinute() < 10 ? `0${this.selectedMinute()}` : this.selectedMinute();
1115
583
  const newValue = `${formattedHour}:${formattedMinute}`;
1116
- this.value = {
584
+ this.value.set({
1117
585
  description: newValue,
1118
586
  value: newValue,
1119
- };
1120
- this.spxChange.emit(this.value);
587
+ });
1121
588
  }
1122
589
  }
1123
590
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTimeComponent, deps: [{ token: i1$3.ModalController }], target: i0.ɵɵFactoryTarget.Component }); }
1124
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.5", type: SpxInputTimeComponent, isStandalone: true, selector: "spx-input-time", inputs: { spxName: "spxName", spxAutofocus: "spxAutofocus", spxInputMode: "spxInputMode", spxPattern: "spxPattern", spxSuggestions: "spxSuggestions", spxReadonly: "spxReadonly", spxValidators: "spxValidators", spxCapitalize: "spxCapitalize", spxFocused: "spxFocused", spxType: "spxType", value: "value", spxWasInternalUpdate: "spxWasInternalUpdate" }, outputs: { spxBlurFromChild: "spxBlurFromChild", spxChange: "spxChange", spxFocus: "spxFocus" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, static: true }], ngImport: i0, template: `<div class="relative text-black">
1125
- <div class="flex items-center justify-around gap-3">
1126
- <div class="grow rounded bg-gray-100 p-3 text-xl text-center font-bold" (click)="openDialog('hours')">{{ formattedHour ?? '--' }}</div>
1127
- <div class="text-gray text-xl">:</div>
1128
- <div class="grow rounded bg-gray-100 p-3 text-xl text-center font-bold" (click)="openDialog('minutes')">{{ formattedMinute ?? '--' }}</div>
1129
- </div>
1130
- </div>`, isInline: true, styles: [".custom-square.selected{background-color:#007bff;color:#fff;border-color:#007bff}.custom-bg{--background: #FFFFFF}\n"] }); }
591
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.2.0", version: "19.0.5", type: SpxInputTimeComponent, isStandalone: true, selector: "spx-input-time", inputs: { spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxAutofocus: { classPropertyName: "spxAutofocus", publicName: "spxAutofocus", isSignal: true, isRequired: false, transformFunction: null }, spxInputMode: { classPropertyName: "spxInputMode", publicName: "spxInputMode", isSignal: true, isRequired: false, transformFunction: null }, spxPattern: { classPropertyName: "spxPattern", publicName: "spxPattern", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxCapitalize: { classPropertyName: "spxCapitalize", publicName: "spxCapitalize", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: true, transformFunction: null } }, outputs: { value: "valueChange" }, viewQueries: [{ propertyName: "inputRef", first: true, predicate: ["input"], descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"relative text-black\">\r\n <div class=\"flex items-center justify-around gap-3\">\r\n <div class=\"grow rounded bg-gray-100 p-3 text-xl text-center font-bold\" (click)=\"openDialog('hours')\">{{ formattedHour() ?? '--' }}</div>\r\n <div class=\"text-gray text-xl\">:</div>\r\n <div class=\"grow rounded bg-gray-100 p-3 text-xl text-center font-bold\" (click)=\"openDialog('minutes')\">{{ formattedMinute() ?? '--' }}</div>\r\n </div>\r\n</div>", styles: [".custom-square.selected{background-color:#007bff;color:#fff;border-color:#007bff}.custom-bg{--background: #FFFFFF}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1131
592
  }
1132
593
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputTimeComponent, decorators: [{
1133
594
  type: Component,
1134
- args: [{ selector: 'spx-input-time', imports: [], template: `<div class="relative text-black">
1135
- <div class="flex items-center justify-around gap-3">
1136
- <div class="grow rounded bg-gray-100 p-3 text-xl text-center font-bold" (click)="openDialog('hours')">{{ formattedHour ?? '--' }}</div>
1137
- <div class="text-gray text-xl">:</div>
1138
- <div class="grow rounded bg-gray-100 p-3 text-xl text-center font-bold" (click)="openDialog('minutes')">{{ formattedMinute ?? '--' }}</div>
1139
- </div>
1140
- </div>`, styles: [".custom-square.selected{background-color:#007bff;color:#fff;border-color:#007bff}.custom-bg{--background: #FFFFFF}\n"] }]
1141
- }], ctorParameters: () => [{ type: i1$3.ModalController }], propDecorators: { spxName: [{
1142
- type: Input
1143
- }], spxAutofocus: [{
1144
- type: Input
1145
- }], spxInputMode: [{
1146
- type: Input
1147
- }], spxPattern: [{
1148
- type: Input
1149
- }], spxSuggestions: [{
1150
- type: Input
1151
- }], spxReadonly: [{
1152
- type: Input
1153
- }], spxValidators: [{
1154
- type: Input
1155
- }], spxCapitalize: [{
1156
- type: Input
1157
- }], spxFocused: [{
1158
- type: Input
1159
- }], spxType: [{
1160
- type: Input
1161
- }], value: [{
1162
- type: Input
1163
- }], spxBlurFromChild: [{
1164
- type: Output
1165
- }], spxChange: [{
1166
- type: Output
1167
- }], spxFocus: [{
1168
- type: Output
1169
- }], spxWasInternalUpdate: [{
1170
- type: Input
1171
- }], inputRef: [{
1172
- type: ViewChild,
1173
- args: ['input', { static: true }]
1174
- }] } });
595
+ args: [{ selector: 'spx-input-time', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"relative text-black\">\r\n <div class=\"flex items-center justify-around gap-3\">\r\n <div class=\"grow rounded bg-gray-100 p-3 text-xl text-center font-bold\" (click)=\"openDialog('hours')\">{{ formattedHour() ?? '--' }}</div>\r\n <div class=\"text-gray text-xl\">:</div>\r\n <div class=\"grow rounded bg-gray-100 p-3 text-xl text-center font-bold\" (click)=\"openDialog('minutes')\">{{ formattedMinute() ?? '--' }}</div>\r\n </div>\r\n</div>", styles: [".custom-square.selected{background-color:#007bff;color:#fff;border-color:#007bff}.custom-bg{--background: #FFFFFF}\n"] }]
596
+ }], ctorParameters: () => [{ type: i1$3.ModalController }] });
1175
597
 
1176
598
  var stepType;
1177
599
  (function (stepType) {
@@ -1185,13 +607,11 @@ class SpxInputDateComponent {
1185
607
  this.spxMin = input.required();
1186
608
  this.spxReadonly = input();
1187
609
  this.spxValidators = input();
610
+ this.spxAutoFocus = input(false);
1188
611
  this.value = model({
1189
612
  description: "",
1190
613
  value: "",
1191
614
  });
1192
- this.spxChange = output();
1193
- this.spxFocused = input(true);
1194
- this.spxFocus = output();
1195
615
  this.spxSelectedStep = signal(stepType.years);
1196
616
  this.spxSelectDay = input(false);
1197
617
  this.spxSelectMonth = input(true);
@@ -1201,6 +621,9 @@ class SpxInputDateComponent {
1201
621
  this.yearInputComponent = viewChild.required(stepType.years);
1202
622
  this.monthInputComponent = viewChild.required(stepType.months);
1203
623
  this.dayInputComponent = viewChild.required(stepType.days);
624
+ this.spxElementId = input();
625
+ this.selectedInputService = inject(SelectedInputService);
626
+ this.spxIsFocused = signal(false);
1204
627
  this.spxSuggestionC = computed(() => {
1205
628
  switch (this.spxSelectedStep()) {
1206
629
  case stepType.years:
@@ -1255,6 +678,7 @@ class SpxInputDateComponent {
1255
678
  switch (selectedStep) {
1256
679
  case stepType.years:
1257
680
  this.spxSelectedStep.set(stepType.years);
681
+ this.yearInputComponent().nativeElement.focus();
1258
682
  break;
1259
683
  case stepType.months:
1260
684
  this.spxSelectedStep.set(stepType.months);
@@ -1281,6 +705,7 @@ class SpxInputDateComponent {
1281
705
  this.selectedDay.set(parsedValue);
1282
706
  break;
1283
707
  }
708
+ this.updateValueAndEmit();
1284
709
  }
1285
710
  ngOnInit() {
1286
711
  this.suggestYears();
@@ -1290,6 +715,16 @@ class SpxInputDateComponent {
1290
715
  this.selectedMonth.set(parsedValue.month);
1291
716
  this.selectedDay.set(parsedValue.day);
1292
717
  }
718
+ if (this.spxAutoFocus()) {
719
+ this.handleFocus("years");
720
+ }
721
+ // Filter updates based on focus state
722
+ this.selectedInputService.focusedElement$
723
+ .pipe(filter((focusedId) => focusedId === this.spxElementId()))
724
+ .subscribe(() => {
725
+ this.spxIsFocused.set(true); // Update only if focused
726
+ this.handleFocus(this.spxSelectedStep());
727
+ });
1293
728
  }
1294
729
  handleSuggestionClick(value) {
1295
730
  switch (this.spxSelectedStep()) {
@@ -1306,11 +741,17 @@ class SpxInputDateComponent {
1306
741
  this.updateValueAndEmit();
1307
742
  this.changeSelectedStep();
1308
743
  }
744
+ // Handle keyboard navigation (Tab and Shift + Tab)
745
+ handleTabKey(event) {
746
+ if (event.key === 'Tab') {
747
+ this.changeSelectedStep();
748
+ event.preventDefault(); // Prevent default tab behavior
749
+ }
750
+ }
1309
751
  updateValueAndEmit() {
1310
752
  const concatenatedValue = `${this.selectedYear() ? this.selectedYear() : ``}${this.selectedMonth() ? `${this.selectedMonth() < 10 ? `0${this.selectedMonth()}` : this.selectedMonth()}` : ``}${this.selectedDay() ? `-${this.selectedDay() < 10 ? `0${this.selectedDay()}` : this.selectedDay()}` : ``}`;
1311
753
  const parsedValue = DateTime.fromISO(concatenatedValue);
1312
754
  this.value.set({ value: parsedValue.toISO(), description: parsedValue.toISO() });
1313
- this.spxChange.emit(this.value());
1314
755
  }
1315
756
  changeSelectedStep() {
1316
757
  switch (this.spxSelectedStep()) {
@@ -1349,118 +790,137 @@ class SpxInputDateComponent {
1349
790
  });
1350
791
  }
1351
792
  }
793
+ handleClear() {
794
+ this.spxSelectedStep.set(stepType.years);
795
+ this.selectedYear.set(null);
796
+ this.selectedMonth.set(null);
797
+ this.selectedDay.set(null);
798
+ }
1352
799
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1353
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputDateComponent, isStandalone: true, selector: "spx-input-date", inputs: { spxMax: { classPropertyName: "spxMax", publicName: "spxMax", isSignal: true, isRequired: true, transformFunction: null }, spxMin: { classPropertyName: "spxMin", publicName: "spxMin", isSignal: true, isRequired: true, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, spxFocused: { classPropertyName: "spxFocused", publicName: "spxFocused", isSignal: true, isRequired: false, transformFunction: null }, spxSelectDay: { classPropertyName: "spxSelectDay", publicName: "spxSelectDay", isSignal: true, isRequired: false, transformFunction: null }, spxSelectMonth: { classPropertyName: "spxSelectMonth", publicName: "spxSelectMonth", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange", spxChange: "spxChange", spxFocus: "spxFocus" }, viewQueries: [{ propertyName: "yearInputComponent", first: true, predicate: stepType.years, descendants: true, isSignal: true }, { propertyName: "monthInputComponent", first: true, predicate: stepType.months, descendants: true, isSignal: true }, { propertyName: "dayInputComponent", first: true, predicate: stepType.days, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='spx-input-date__controls'>\n <input #years\n class='spx-input-date__input'\n [(ngModel)]=\"selectedYear\"\n [attr.type]=\"'number'\"\n (click)=\"this.handleFocus('years')\"\n (ngModelChange)=\"onModelChange($event, 'years')\"\n [attr.min]=\"1900\"\n [attr.max]=\"2100\"\n [attr.step]=\"1\"\n />\n <div class='spx-input-date__control-label'>Year</div>\n @if (this.spxSelectMonth()) {\n <input #months\n class='spx-input-date__input'\n [(ngModel)]=\"selectedMonth\"\n (ngModelChange)=\"onModelChange($event, 'months')\"\n (click)=\"this.handleFocus('months')\"\n [attr.type]=\"'number'\"\n [attr.min]=\"1\"\n [attr.max]=\"12\"\n [attr.step]=\"1\" />\n }\n <div class='spx-input-date__control-label'>Month</div>\n @if (this.spxSelectDay()) {\n <input #days\n class='spx-input-date__input'\n [(ngModel)]=\"selectedDay\"\n (ngModelChange)=\"onModelChange($event, 'days')\"\n (click)=\"this.handleFocus('days')\"\n [attr.type]=\"'number'\"\n [attr.min]=\"1\"\n [attr.max]=\"31\"\n [attr.step]=\"1\" />\n <div class='spx-input-date__control-label'>Days</div>\n }\n</div>\n<div class='spx-input-date__suggestions'>\n @for (valuePair of spxSuggestionC(); track valuePair.value) {\n <spx-suggestion [spxSelected]=\"\n (selectedYear() === valuePair.value) ||\n (selectedMonth() === valuePair.value) || \n (selectedDay() === valuePair.value)\"\n (click)=\"this.handleSuggestionClick(valuePair.value)\">{{valuePair?.description}}</spx-suggestion>\n }\n</div>", styles: [":host{display:block}.spx-input-date__input{background-color:transparent;border:1px solid #979797;border-radius:4px;color:var(--spx-input--color, rgba(0, 0, 0, .9));box-sizing:border-box;font-size:16px;margin-right:10px;padding:6px;text-align:center;width:100%}.spx-input-date__input:active{transform:scale(.95)}.spx-input-date__input:focus{border:var(--spx-input-box--focus--border, 1px solid rgb(115, 168, 210));border-radius:4px;outline:none}.spx-input-date__control-label{align-items:center;color:#000000b3;display:inline-grid;font-size:13px;letter-spacing:1px}.spx-input-date__input::-webkit-outer-spin-button,.spx-input-date__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.spx-input-date__input[type=number]{-moz-appearance:textfield}.spx-input-date__suggestions,.spx-input-date__controls{display:grid;grid-gap:8px;grid-template-columns:repeat(4,1fr);margin-top:8px}\n"], dependencies: [{ kind: "component", type: SpxSuggestionComponent, selector: "spx-suggestion", inputs: ["spxDisabled", "spxFocused", "spxSelected", "spxTabbable"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }] }); }
800
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputDateComponent, isStandalone: true, selector: "spx-input-date", inputs: { spxMax: { classPropertyName: "spxMax", publicName: "spxMax", isSignal: true, isRequired: true, transformFunction: null }, spxMin: { classPropertyName: "spxMin", publicName: "spxMin", isSignal: true, isRequired: true, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxAutoFocus: { classPropertyName: "spxAutoFocus", publicName: "spxAutoFocus", isSignal: true, isRequired: false, transformFunction: null }, value: { classPropertyName: "value", publicName: "value", isSignal: true, isRequired: false, transformFunction: null }, spxSelectDay: { classPropertyName: "spxSelectDay", publicName: "spxSelectDay", isSignal: true, isRequired: false, transformFunction: null }, spxSelectMonth: { classPropertyName: "spxSelectMonth", publicName: "spxSelectMonth", isSignal: true, isRequired: false, transformFunction: null }, spxElementId: { classPropertyName: "spxElementId", publicName: "spxElementId", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { value: "valueChange" }, host: { listeners: { "keydown": "handleTabKey($event)" } }, viewQueries: [{ propertyName: "yearInputComponent", first: true, predicate: stepType.years, descendants: true, isSignal: true }, { propertyName: "monthInputComponent", first: true, predicate: stepType.months, descendants: true, isSignal: true }, { propertyName: "dayInputComponent", first: true, predicate: stepType.days, descendants: true, isSignal: true }], ngImport: i0, template: "<div class='spx-input-date__controls'>\r\n <input #years\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedYear()\"\r\n (ngModelChange)=\"onModelChange($event, 'years')\"\r\n [attr.type]=\"'number'\"\r\n (click)=\"this.handleFocus('years')\"\r\n [attr.min]=\"1900\"\r\n [attr.max]=\"2100\"\r\n [attr.step]=\"1\"\r\n />\r\n <div class='spx-input-date__control-label'>Year</div>\r\n @if (this.spxSelectMonth()) {\r\n <input #months\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedMonth()\"\r\n (ngModelChange)=\"onModelChange($event, 'months')\"\r\n (click)=\"this.handleFocus('months')\"\r\n [attr.type]=\"'number'\"\r\n [attr.min]=\"1\"\r\n [attr.max]=\"12\"\r\n [attr.step]=\"1\" />\r\n }\r\n <div class='spx-input-date__control-label'>Month</div>\r\n @if (this.spxSelectDay()) {\r\n <input #days\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedDay()\"\r\n (ngModelChange)=\"onModelChange($event, 'days')\"\r\n (click)=\"this.handleFocus('days')\"\r\n [attr.type]=\"'number'\"\r\n [attr.min]=\"1\"\r\n [attr.max]=\"31\"\r\n [attr.step]=\"1\" />\r\n <div class='spx-input-date__control-label'>Days</div>\r\n }\r\n</div>\r\n<div class='spx-input-date__suggestions'>\r\n @for (valuePair of spxSuggestionC(); track valuePair.value) {\r\n <spx-suggestion [spxSelected]=\"\r\n (selectedYear() === valuePair.value && this.spxSelectedStep() === 'years') ||\r\n (selectedMonth() === valuePair.value && this.spxSelectedStep() === 'months') || \r\n (selectedDay() === valuePair.value && this.spxSelectedStep() === 'days')\"\r\n (click)=\"this.handleSuggestionClick(valuePair.value)\">{{valuePair?.description}}</spx-suggestion>\r\n }\r\n</div>", styles: [":host{display:block}.spx-input-date__input{background-color:transparent;border:1px solid #979797;border-radius:4px;color:var(--spx-input--color, rgba(0, 0, 0, .9));box-sizing:border-box;font-size:16px;margin-right:10px;padding:6px;text-align:center;width:100%}.spx-input-date__input:active{transform:scale(.95)}.spx-input-date__input:focus{border:var(--spx-input-box--focus--border, 1px solid rgb(115, 168, 210));border-radius:4px;outline:none}.spx-input-date__control-label{align-items:center;color:#000000b3;display:inline-grid;font-size:13px;letter-spacing:1px}.spx-input-date__input::-webkit-outer-spin-button,.spx-input-date__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.spx-input-date__input[type=number]{-moz-appearance:textfield}.spx-input-date__suggestions,.spx-input-date__controls{display:grid;grid-gap:8px;grid-template-columns:repeat(4,1fr);margin-top:8px}\n"], dependencies: [{ kind: "component", type: SpxSuggestionComponent, selector: "spx-suggestion", inputs: ["spxDisabled", "spxFocused", "spxSelected", "spxTabbable"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$1.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: i1$1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1354
801
  }
1355
802
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputDateComponent, decorators: [{
1356
803
  type: Component,
1357
- args: [{ selector: 'spx-input-date', imports: [
804
+ args: [{ selector: 'spx-input-date', standalone: true, imports: [
1358
805
  SpxSuggestionComponent,
1359
806
  FormsModule
1360
- ], template: "<div class='spx-input-date__controls'>\n <input #years\n class='spx-input-date__input'\n [(ngModel)]=\"selectedYear\"\n [attr.type]=\"'number'\"\n (click)=\"this.handleFocus('years')\"\n (ngModelChange)=\"onModelChange($event, 'years')\"\n [attr.min]=\"1900\"\n [attr.max]=\"2100\"\n [attr.step]=\"1\"\n />\n <div class='spx-input-date__control-label'>Year</div>\n @if (this.spxSelectMonth()) {\n <input #months\n class='spx-input-date__input'\n [(ngModel)]=\"selectedMonth\"\n (ngModelChange)=\"onModelChange($event, 'months')\"\n (click)=\"this.handleFocus('months')\"\n [attr.type]=\"'number'\"\n [attr.min]=\"1\"\n [attr.max]=\"12\"\n [attr.step]=\"1\" />\n }\n <div class='spx-input-date__control-label'>Month</div>\n @if (this.spxSelectDay()) {\n <input #days\n class='spx-input-date__input'\n [(ngModel)]=\"selectedDay\"\n (ngModelChange)=\"onModelChange($event, 'days')\"\n (click)=\"this.handleFocus('days')\"\n [attr.type]=\"'number'\"\n [attr.min]=\"1\"\n [attr.max]=\"31\"\n [attr.step]=\"1\" />\n <div class='spx-input-date__control-label'>Days</div>\n }\n</div>\n<div class='spx-input-date__suggestions'>\n @for (valuePair of spxSuggestionC(); track valuePair.value) {\n <spx-suggestion [spxSelected]=\"\n (selectedYear() === valuePair.value) ||\n (selectedMonth() === valuePair.value) || \n (selectedDay() === valuePair.value)\"\n (click)=\"this.handleSuggestionClick(valuePair.value)\">{{valuePair?.description}}</spx-suggestion>\n }\n</div>", styles: [":host{display:block}.spx-input-date__input{background-color:transparent;border:1px solid #979797;border-radius:4px;color:var(--spx-input--color, rgba(0, 0, 0, .9));box-sizing:border-box;font-size:16px;margin-right:10px;padding:6px;text-align:center;width:100%}.spx-input-date__input:active{transform:scale(.95)}.spx-input-date__input:focus{border:var(--spx-input-box--focus--border, 1px solid rgb(115, 168, 210));border-radius:4px;outline:none}.spx-input-date__control-label{align-items:center;color:#000000b3;display:inline-grid;font-size:13px;letter-spacing:1px}.spx-input-date__input::-webkit-outer-spin-button,.spx-input-date__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.spx-input-date__input[type=number]{-moz-appearance:textfield}.spx-input-date__suggestions,.spx-input-date__controls{display:grid;grid-gap:8px;grid-template-columns:repeat(4,1fr);margin-top:8px}\n"] }]
1361
- }] });
807
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class='spx-input-date__controls'>\r\n <input #years\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedYear()\"\r\n (ngModelChange)=\"onModelChange($event, 'years')\"\r\n [attr.type]=\"'number'\"\r\n (click)=\"this.handleFocus('years')\"\r\n [attr.min]=\"1900\"\r\n [attr.max]=\"2100\"\r\n [attr.step]=\"1\"\r\n />\r\n <div class='spx-input-date__control-label'>Year</div>\r\n @if (this.spxSelectMonth()) {\r\n <input #months\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedMonth()\"\r\n (ngModelChange)=\"onModelChange($event, 'months')\"\r\n (click)=\"this.handleFocus('months')\"\r\n [attr.type]=\"'number'\"\r\n [attr.min]=\"1\"\r\n [attr.max]=\"12\"\r\n [attr.step]=\"1\" />\r\n }\r\n <div class='spx-input-date__control-label'>Month</div>\r\n @if (this.spxSelectDay()) {\r\n <input #days\r\n class='spx-input-date__input'\r\n [ngModel]=\"selectedDay()\"\r\n (ngModelChange)=\"onModelChange($event, 'days')\"\r\n (click)=\"this.handleFocus('days')\"\r\n [attr.type]=\"'number'\"\r\n [attr.min]=\"1\"\r\n [attr.max]=\"31\"\r\n [attr.step]=\"1\" />\r\n <div class='spx-input-date__control-label'>Days</div>\r\n }\r\n</div>\r\n<div class='spx-input-date__suggestions'>\r\n @for (valuePair of spxSuggestionC(); track valuePair.value) {\r\n <spx-suggestion [spxSelected]=\"\r\n (selectedYear() === valuePair.value && this.spxSelectedStep() === 'years') ||\r\n (selectedMonth() === valuePair.value && this.spxSelectedStep() === 'months') || \r\n (selectedDay() === valuePair.value && this.spxSelectedStep() === 'days')\"\r\n (click)=\"this.handleSuggestionClick(valuePair.value)\">{{valuePair?.description}}</spx-suggestion>\r\n }\r\n</div>", styles: [":host{display:block}.spx-input-date__input{background-color:transparent;border:1px solid #979797;border-radius:4px;color:var(--spx-input--color, rgba(0, 0, 0, .9));box-sizing:border-box;font-size:16px;margin-right:10px;padding:6px;text-align:center;width:100%}.spx-input-date__input:active{transform:scale(.95)}.spx-input-date__input:focus{border:var(--spx-input-box--focus--border, 1px solid rgb(115, 168, 210));border-radius:4px;outline:none}.spx-input-date__control-label{align-items:center;color:#000000b3;display:inline-grid;font-size:13px;letter-spacing:1px}.spx-input-date__input::-webkit-outer-spin-button,.spx-input-date__input::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.spx-input-date__input[type=number]{-moz-appearance:textfield}.spx-input-date__suggestions,.spx-input-date__controls{display:grid;grid-gap:8px;grid-template-columns:repeat(4,1fr);margin-top:8px}\n"] }]
808
+ }], propDecorators: { handleTabKey: [{
809
+ type: HostListener,
810
+ args: ['keydown', ['$event']]
811
+ }] } });
1362
812
 
1363
813
  class SpxInputComponent {
1364
814
  constructor() {
1365
- this.spxLabel = 'label';
1366
- this.spxReadonly = false;
1367
- this.spxAutofocus = false;
1368
- this.spxRequired = false;
1369
- this.spxSelectMonth = true;
1370
- this.spxSelectDay = true;
1371
- this.spxShowEdit = false;
1372
- this.spxShowHelp = false;
1373
- this.spxShowLabel = true;
1374
- this.spxCompact = false;
1375
- this.spxShowClear = true;
1376
- this.spxShowSearch = false;
1377
- this.spxShowValidationMessages = false;
1378
- this.spxSuggestions = [];
1379
- this.spxType = SpxInputTypeEnum.text;
1380
- this.spxCapitalize = false;
1381
- this.spxBlur = new EventEmitter();
1382
- this.spxClear = new EventEmitter();
1383
- this.spxChange = new EventEmitter();
1384
- this.spxFocus = new EventEmitter();
1385
- this.spxEdit = new EventEmitter();
1386
- this.spxHelp = new EventEmitter();
1387
- this.spxSearch = new EventEmitter();
1388
- this.spxFocused = false;
815
+ this.spxLabel = input('label');
816
+ this.spxMax = input();
817
+ this.spxMin = input();
818
+ this.spxName = input();
819
+ this.spxReadonly = input(false);
820
+ this.spxAutocomplete = input();
821
+ this.spxAutofocus = input(false);
822
+ this.spxInputMode = input();
823
+ this.spxPattern = input();
824
+ this.spxRequired = input(false);
825
+ this.spxSelectMonth = input(true);
826
+ this.spxSelectDay = input(true);
827
+ this.spxShowEdit = input(false);
828
+ this.spxShowHelp = input(false);
829
+ this.spxShowLabel = input(true);
830
+ this.spxCompact = input(false);
831
+ this.spxShowClear = input(true);
832
+ this.spxShowSearch = input(false);
833
+ this.spxShowValidationMessages = input(false);
834
+ this.spxStep = input();
835
+ this.spxSuggestions = input([]);
836
+ this.spxType = input(SpxInputTypeEnum.text);
837
+ this.spxValidators = input();
838
+ this.spxCapitalize = input(false);
839
+ this.value = signal({ value: null, description: null });
840
+ this.spxClear = output();
841
+ this.spxEdit = output();
842
+ this.spxHelp = output();
843
+ this.spxSearch = output();
844
+ this.spxBlur = output();
845
+ this.floatInput = viewChild("spxInputFloat");
846
+ this.numberInput = viewChild("spxInputNumber");
847
+ this.textInput = viewChild("spxInputText");
848
+ this.timeInput = viewChild("spxInputTime");
849
+ this.radioInput = viewChild("spxInputRadio");
850
+ this.dateInput = viewChild("spxInputDate");
851
+ this.spxElementId = signal(0);
852
+ this.selectedInputService = inject(SelectedInputService);
1389
853
  this.onChange = () => { };
1390
854
  this.onTouched = () => { };
1391
855
  }
1392
- handleBlur() {
1393
- this.spxBlur.emit();
856
+ handleSpxElementIdSet(id) {
857
+ this.spxElementId.set(id);
858
+ this.selectedInputServiceSubscription = this.selectedInputService.isBlurred$(id).subscribe((isBlurred) => {
859
+ if (isBlurred) {
860
+ this.spxBlur.emit();
861
+ }
862
+ });
863
+ }
864
+ ngOnDestroy() {
865
+ if (this.selectedInputServiceSubscription) {
866
+ this.selectedInputServiceSubscription.unsubscribe();
867
+ }
1394
868
  }
1395
869
  handleChange(event) {
1396
- this.value = event;
1397
- this.spxChange.emit(this.value);
870
+ this.value.set(event);
1398
871
  }
1399
872
  handleClear() {
1400
873
  this.spxClear.emit();
1401
- this.spxFocused = true;
1402
874
  this.passFocusToControl();
1403
- this.value = {
1404
- description: null,
875
+ this.handleChangeEvent({
1405
876
  value: null,
1406
- };
1407
- this.spxChange.emit(this.value);
1408
- }
1409
- handleFocus() {
1410
- this.spxFocus.emit();
1411
- this.spxFocused = true;
877
+ });
878
+ this.dateInput()?.handleClear();
879
+ this.floatInput()?.handleClear();
1412
880
  }
1413
881
  handleSearch() {
1414
882
  this.spxSearch.emit();
1415
883
  }
1416
- setFocusIn() {
1417
- setTimeout(() => {
1418
- this.spxFocused = true;
1419
- this.passFocusToControl();
1420
- }, 0);
1421
- }
1422
- setFocusOut() {
1423
- setTimeout(() => {
1424
- this.spxFocused = false;
1425
- if (this.spxType === SpxInputTypeEnum.radio) {
1426
- this.radioInput?.spxFocusOut();
1427
- }
1428
- }, 0);
1429
- }
1430
884
  handleEdit() {
1431
885
  this.spxEdit.emit();
1432
- this.spxFocused = true;
1433
886
  }
1434
887
  handleHelp() {
1435
888
  this.spxHelp.emit();
1436
- this.spxFocused = true;
889
+ }
890
+ setFocusIn() {
891
+ setTimeout(() => {
892
+ this.passFocusToControl();
893
+ }, 0);
1437
894
  }
1438
895
  passFocusToControl() {
1439
- switch (this.spxType) {
896
+ switch (this.spxType()) {
1440
897
  case SpxInputTypeEnum.autocomplete:
1441
898
  case SpxInputTypeEnum.text:
1442
899
  case SpxInputTypeEnum.overlayNumber:
1443
- this.textInput?.spxSetFocus();
900
+ this.textInput()?.spxSetFocus();
1444
901
  break;
1445
902
  case SpxInputTypeEnum.number:
1446
- this.numberInput?.spxSetFocus();
903
+ this.numberInput()?.spxSetFocus();
1447
904
  break;
1448
905
  case SpxInputTypeEnum.radio:
1449
- this.radioInput?.spxFocusIn();
1450
906
  break;
1451
907
  case SpxInputTypeEnum.time:
1452
- this.timeInput?.spxSetFocus();
908
+ this.timeInput()?.spxSetFocus();
1453
909
  break;
1454
910
  }
1455
911
  }
1456
912
  writeValue(value) {
1457
- this.value = this.lastValue = value; // hier komt initiele waarde van formcontrol binnen
913
+ if (value === null)
914
+ return;
915
+ this.value.set(value); // hier komt initiele waarde van formcontrol binnen
916
+ this.lastValue = value;
1458
917
  }
1459
918
  handleChangeEvent(value) {
1460
919
  if (value !== this.lastValue) {
1461
920
  this.lastValue = value;
1462
921
  this.onChange(value);
1463
922
  }
923
+ this.writeValue(value);
1464
924
  }
1465
925
  _handleBlurEvent() {
1466
926
  this.onTouched();
@@ -1472,131 +932,19 @@ class SpxInputComponent {
1472
932
  this.onTouched = fn;
1473
933
  }
1474
934
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
1475
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputComponent, isStandalone: true, selector: "spx-input", inputs: { spxLabel: "spxLabel", spxMax: "spxMax", spxMin: "spxMin", spxName: "spxName", spxReadonly: "spxReadonly", spxAutocomplete: "spxAutocomplete", spxAutofocus: "spxAutofocus", spxInputMode: "spxInputMode", spxPattern: "spxPattern", spxRequired: "spxRequired", spxSelectMonth: "spxSelectMonth", spxSelectDay: "spxSelectDay", spxShowEdit: "spxShowEdit", spxShowHelp: "spxShowHelp", spxShowLabel: "spxShowLabel", spxCompact: "spxCompact", spxShowClear: "spxShowClear", spxShowSearch: "spxShowSearch", spxShowValidationMessages: "spxShowValidationMessages", spxStep: "spxStep", spxSuggestions: "spxSuggestions", spxType: "spxType", spxValidators: "spxValidators", value: "value", spxCapitalize: "spxCapitalize", spxFocused: "spxFocused" }, outputs: { spxBlur: "spxBlur", spxClear: "spxClear", spxChange: "spxChange", spxFocus: "spxFocus", spxEdit: "spxEdit", spxHelp: "spxHelp", spxSearch: "spxSearch" }, host: { listeners: { "spxChange": "handleChangeEvent($event)", "focusout": "_handleBlurEvent()" } }, providers: [
935
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.5", type: SpxInputComponent, isStandalone: true, selector: "spx-input", inputs: { spxLabel: { classPropertyName: "spxLabel", publicName: "spxLabel", isSignal: true, isRequired: false, transformFunction: null }, spxMax: { classPropertyName: "spxMax", publicName: "spxMax", isSignal: true, isRequired: false, transformFunction: null }, spxMin: { classPropertyName: "spxMin", publicName: "spxMin", isSignal: true, isRequired: false, transformFunction: null }, spxName: { classPropertyName: "spxName", publicName: "spxName", isSignal: true, isRequired: false, transformFunction: null }, spxReadonly: { classPropertyName: "spxReadonly", publicName: "spxReadonly", isSignal: true, isRequired: false, transformFunction: null }, spxAutocomplete: { classPropertyName: "spxAutocomplete", publicName: "spxAutocomplete", isSignal: true, isRequired: false, transformFunction: null }, spxAutofocus: { classPropertyName: "spxAutofocus", publicName: "spxAutofocus", isSignal: true, isRequired: false, transformFunction: null }, spxInputMode: { classPropertyName: "spxInputMode", publicName: "spxInputMode", isSignal: true, isRequired: false, transformFunction: null }, spxPattern: { classPropertyName: "spxPattern", publicName: "spxPattern", isSignal: true, isRequired: false, transformFunction: null }, spxRequired: { classPropertyName: "spxRequired", publicName: "spxRequired", isSignal: true, isRequired: false, transformFunction: null }, spxSelectMonth: { classPropertyName: "spxSelectMonth", publicName: "spxSelectMonth", isSignal: true, isRequired: false, transformFunction: null }, spxSelectDay: { classPropertyName: "spxSelectDay", publicName: "spxSelectDay", isSignal: true, isRequired: false, transformFunction: null }, spxShowEdit: { classPropertyName: "spxShowEdit", publicName: "spxShowEdit", isSignal: true, isRequired: false, transformFunction: null }, spxShowHelp: { classPropertyName: "spxShowHelp", publicName: "spxShowHelp", isSignal: true, isRequired: false, transformFunction: null }, spxShowLabel: { classPropertyName: "spxShowLabel", publicName: "spxShowLabel", isSignal: true, isRequired: false, transformFunction: null }, spxCompact: { classPropertyName: "spxCompact", publicName: "spxCompact", isSignal: true, isRequired: false, transformFunction: null }, spxShowClear: { classPropertyName: "spxShowClear", publicName: "spxShowClear", isSignal: true, isRequired: false, transformFunction: null }, spxShowSearch: { classPropertyName: "spxShowSearch", publicName: "spxShowSearch", isSignal: true, isRequired: false, transformFunction: null }, spxShowValidationMessages: { classPropertyName: "spxShowValidationMessages", publicName: "spxShowValidationMessages", isSignal: true, isRequired: false, transformFunction: null }, spxStep: { classPropertyName: "spxStep", publicName: "spxStep", isSignal: true, isRequired: false, transformFunction: null }, spxSuggestions: { classPropertyName: "spxSuggestions", publicName: "spxSuggestions", isSignal: true, isRequired: false, transformFunction: null }, spxType: { classPropertyName: "spxType", publicName: "spxType", isSignal: true, isRequired: false, transformFunction: null }, spxValidators: { classPropertyName: "spxValidators", publicName: "spxValidators", isSignal: true, isRequired: false, transformFunction: null }, spxCapitalize: { classPropertyName: "spxCapitalize", publicName: "spxCapitalize", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { spxClear: "spxClear", spxEdit: "spxEdit", spxHelp: "spxHelp", spxSearch: "spxSearch", spxBlur: "spxBlur" }, host: { listeners: { "spxChange": "handleChangeEvent($event)", "focusout": "_handleBlurEvent()" } }, providers: [
1476
936
  {
1477
937
  provide: NG_VALUE_ACCESSOR,
1478
938
  useExisting: SpxInputComponent,
1479
939
  multi: true
1480
940
  }
1481
- ], viewQueries: [{ propertyName: "floatInput", first: true, predicate: SpxInputFloatComponent, descendants: true }, { propertyName: "numberInput", first: true, predicate: SpxInputNumberComponent, descendants: true }, { propertyName: "textInput", first: true, predicate: SpxInputTextComponent, descendants: true }, { propertyName: "timeInput", first: true, predicate: SpxInputTimeComponent, descendants: true }, { propertyName: "radioInput", first: true, predicate: SpxInputRadioComponent, descendants: true }], ngImport: i0, template: `<spx-input-box
1482
- [spxFocused]="this.spxFocused"
1483
- [spxLabel]="this.spxLabel"
1484
- [spxReadonly]="this.spxReadonly"
1485
- [spxRequired]="this.spxRequired"
1486
- [spxValue]="this.value"
1487
- [spxShowHelp]="this.spxShowHelp"
1488
- [spxCompact]="this.spxCompact"
1489
- [spxShowClear]="this.spxShowClear"
1490
- [spxShowEdit]="this.spxShowEdit"
1491
- [spxShowLabel]="this.spxShowLabel"
1492
- [spxShowSearch]="this.spxShowSearch ? this.spxShowSearch : this.spxType === 'autocomplete'"
1493
- [spxShowValidationMessages]="this.spxShowValidationMessages"
1494
- (spxClear)="this.handleClear()"
1495
- (spxEdit)="this.handleEdit()"
1496
- (spxHelp)="this.handleHelp()"
1497
- (spxFocus)="this.setFocusIn()"
1498
- (spxFocusOut)="this.setFocusOut()"
1499
- (spxSearch)="this.handleSearch()">
1500
- <div controls>
1501
- @if (this.spxType === 'autocomplete' || this.spxType === 'overlay' || this.spxType === 'overlaynumber' || this.spxType === 'text' || this.spxType === 'password') {
1502
- <spx-input-text
1503
- (spxBlurFromChild)="this.handleBlur()"
1504
- (spxChange)="this.handleChange($event)"
1505
- (spxFocus)="this.handleFocus()"
1506
- [spxAutocomplete]="this.spxAutocomplete ? this.spxAutocomplete : undefined"
1507
- [spxAutofocus]="this.spxAutofocus"
1508
- [spxCapitalize]="this.spxCapitalize"
1509
- [spxFocused]="this.spxFocused"
1510
- [spxInputMode]="this.spxType === 'overlaynumber' ? 'numeric' : this.spxInputMode"
1511
- [spxName]="this.spxName"
1512
- [spxPattern]="this.spxType === 'overlaynumber' ? '[0-9]*' : this.spxPattern"
1513
- [spxReadonly]="this.spxReadonly"
1514
- [spxSuggestions]="this.spxSuggestions"
1515
- [spxType]="this.spxType"
1516
- [spxValidators]="this.spxValidators"
1517
- [value]="this.value"
1518
- ></spx-input-text>
1519
- }
1520
- @if (this.spxType === 'date') {
1521
- <spx-input-date
1522
- (spxChange)="this.handleChange($event)"
1523
- (spxFocus)="this.handleFocus()"
1524
- [spxFocused]="this.spxFocused"
1525
- [spxMax]="this.spxMax!"
1526
- [spxMin]="this.spxMin!"
1527
- [spxReadonly]="this.spxReadonly"
1528
- [spxSelectDay]="this.spxSelectDay"
1529
- [spxSelectMonth]="this.spxSelectMonth"
1530
- [spxValidators]="this.spxValidators"
1531
- [(value)]="this.value"
1532
- ></spx-input-date>
1533
- }
1534
- @if (this.spxType === 'float') {
1535
- <spx-input-float
1536
- (spxChange)="this.handleChange($event)"
1537
- (spxFocus)="this.handleFocus()"
1538
- [spxAutofocus]="this.spxAutofocus"
1539
- [spxFocused]="this.spxFocused"
1540
- [spxName]="this.spxName"
1541
- [spxReadonly]="this.spxReadonly"
1542
- [spxStep]="this.spxStep"
1543
- [spxValidators]="this.spxValidators"
1544
- [value]="this.value"
1545
- ></spx-input-float>
1546
- }
1547
- @if (this.spxType === 'number') {
1548
- <spx-input-number
1549
- (spxChange)="this.handleChange($event)"
1550
- (spxFocus)="this.handleFocus()"
1551
- [spxAutofocus]="this.spxAutofocus"
1552
- [spxFocused]="this.spxFocused"
1553
- [spxInputMode]="this.spxInputMode"
1554
- [spxName]="this.spxName"
1555
- [spxReadonly]="this.spxReadonly"
1556
- [spxStep]="this.spxStep"
1557
- [spxValidators]="this.spxValidators"
1558
- [value]="this.value"
1559
- ></spx-input-number>
1560
- }
1561
- @if (this.spxType === 'radio') {
1562
- <spx-input-radio
1563
- #radioInput
1564
- (spxChange)="this.handleChange($event)"
1565
- [spxFocused]="this.spxFocused"
1566
- [spxName]="this.spxName"
1567
- [spxReadonly]="this.spxReadonly"
1568
- [spxShowLabel]="this.spxShowLabel"
1569
- [spxSuggestions]="this.spxSuggestions"
1570
- [spxValidators]="this.spxValidators"
1571
- [value]="this.value"
1572
- ></spx-input-radio>
1573
- }
1574
- @if (this.spxType === 'time') {
1575
- <spx-input-time
1576
- #timeInput
1577
- (spxChange)="this.handleChange($event)"
1578
- (spxFocus)="this.handleFocus()"
1579
- [spxFocused]="this.spxFocused"
1580
- [spxName]="this.spxName"
1581
- [spxReadonly]="this.spxReadonly"
1582
- [spxValidators]="this.spxValidators"
1583
- [value]="this.value"
1584
- ></spx-input-time>
1585
- }
1586
- </div>
1587
- <div validation-messages>
1588
- <ng-content></ng-content>
1589
- </div>
1590
- </spx-input-box>`, isInline: true, dependencies: [{ kind: "component", type: SpxInputBoxComponent, selector: "spx-input-box", inputs: ["spxCompact", "spxFocused", "spxLabel", "spxReadonly", "spxRequired", "spxShowClear", "spxShowEdit", "spxShowHelp", "spxShowLabel", "spxShowSearch", "spxShowValidationMessages", "spxValue"], outputs: ["spxClear", "spxSearch", "spxFocus", "spxFocusOut", "spxEdit", "spxHelp"] }, { kind: "component", type: SpxInputDateComponent, selector: "spx-input-date", inputs: ["spxMax", "spxMin", "spxReadonly", "spxValidators", "value", "spxFocused", "spxSelectDay", "spxSelectMonth", "spxSuggestions"], outputs: ["valueChange", "spxChange", "spxFocus"] }, { kind: "component", type: SpxInputFloatComponent, selector: "spx-input-float", inputs: ["spxName", "spxAutofocus", "spxReadonly", "spxValidators", "spxFocused", "spxStep", "value", "spxWasInternalUpdate", "tick"], outputs: ["spxChange", "spxFocus"] }, { kind: "component", type: SpxInputNumberComponent, selector: "spx-input-number", inputs: ["spxName", "spxAutofocus", "spxInputMode", "spxReadonly", "spxValidators", "spxFocused", "spxStep", "value"], outputs: ["spxChange", "spxFocus"] }, { kind: "component", type: SpxInputRadioComponent, selector: "spx-input-radio", inputs: ["spxName", "spxValidators", "spxFocused", "spxShowLabel", "spxReadonly", "spxSuggestions", "value"], outputs: ["spxChange", "spxFocus"] }, { kind: "component", type: SpxInputTextComponent, selector: "spx-input-text", inputs: ["spxName", "spxAutofocus", "spxAutocomplete", "spxInputMode", "spxPattern", "spxSuggestions", "spxReadonly", "spxValidators", "spxCapitalize", "spxFocused", "spxType", "value", "spxWasInternalUpdate"], outputs: ["spxBlurFromChild", "spxChange", "spxFocus"] }, { kind: "component", type: SpxInputTimeComponent, selector: "spx-input-time", inputs: ["spxName", "spxAutofocus", "spxInputMode", "spxPattern", "spxSuggestions", "spxReadonly", "spxValidators", "spxCapitalize", "spxFocused", "spxType", "value", "spxWasInternalUpdate"], outputs: ["spxBlurFromChild", "spxChange", "spxFocus"] }] }); }
941
+ ], viewQueries: [{ propertyName: "floatInput", first: true, predicate: ["spxInputFloat"], descendants: true, isSignal: true }, { propertyName: "numberInput", first: true, predicate: ["spxInputNumber"], descendants: true, isSignal: true }, { propertyName: "textInput", first: true, predicate: ["spxInputText"], descendants: true, isSignal: true }, { propertyName: "timeInput", first: true, predicate: ["spxInputTime"], descendants: true, isSignal: true }, { propertyName: "radioInput", first: true, predicate: ["spxInputRadio"], descendants: true, isSignal: true }, { propertyName: "dateInput", first: true, predicate: ["spxInputDate"], descendants: true, isSignal: true }], ngImport: i0, template: "<spx-input-box\r\n [spxLabel]=\"this.spxLabel()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxRequired]=\"this.spxRequired()\"\r\n [spxValue]=\"this.value()\"\r\n [spxShowHelp]=\"this.spxShowHelp()\"\r\n [spxCompact]=\"this.spxCompact()\"\r\n [spxShowClear]=\"this.spxShowClear()\"\r\n [spxShowEdit]=\"this.spxShowEdit()\"\r\n [spxShowLabel]=\"this.spxShowLabel()\"\r\n [spxShowSearch]=\"this.spxShowSearch() ? this.spxShowSearch() : this.spxType() === 'autocomplete'\"\r\n [spxShowValidationMessages]=\"this.spxShowValidationMessages()\"\r\n (spxClear)=\"this.handleClear()\"\r\n (spxEdit)=\"this.handleEdit()\"\r\n (spxHelp)=\"this.handleHelp()\"\r\n (spxSearch)=\"this.handleSearch()\"\r\n (spxSetIdInParent)=\"handleSpxElementIdSet($event)\"\r\n >\r\n <div controls>\r\n @if (this.spxType() === 'autocomplete' || this.spxType() === 'overlay' || this.spxType() === 'overlaynumber' || this.spxType() === 'text' || this.spxType() === 'password') {\r\n <spx-input-text #spxInputText\r\n [spxAutocomplete]=\"this.spxAutocomplete() ? this.spxAutocomplete() : undefined\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxCapitalize]=\"this.spxCapitalize()\"\r\n [spxInputMode]=\"this.spxType() === 'overlaynumber' ? 'numeric' : this.spxInputMode()\"\r\n [spxName]=\"this.spxName()\"\r\n [spxPattern]=\"this.spxType() === 'overlaynumber' ? '[0-9]*' : this.spxPattern()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxSuggestions]=\"this.spxSuggestions()\"\r\n [spxType]=\"this.spxType()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-text>\r\n }\r\n @if (this.spxType() === 'date') {\r\n <spx-input-date #spxInputDate\r\n [spxMax]=\"this.spxMax()!\"\r\n [spxMin]=\"this.spxMin()!\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxSelectDay]=\"this.spxSelectDay()\"\r\n [spxSelectMonth]=\"this.spxSelectMonth()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [spxAutoFocus]=\"this.spxAutofocus()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-date>\r\n }\r\n @if (this.spxType() === 'float') {\r\n <spx-input-float #spxInputFloat\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxStep]=\"this.spxStep()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-float>\r\n }\r\n @if (this.spxType() === 'number') {\r\n <spx-input-number #spxInputNumber\r\n [spxInputMode]=\"this.spxInputMode()\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxStep]=\"this.spxStep()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-number>\r\n }\r\n @if (this.spxType() === 'radio') {\r\n <spx-input-radio\r\n #spxInputRadio\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxShowLabel]=\"this.spxShowLabel()\"\r\n [spxSuggestions]=\"this.spxSuggestions()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-radio>\r\n }\r\n @if (this.spxType() === 'time') {\r\n <spx-input-time\r\n #spxInputTime\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-time>\r\n }\r\n </div>\r\n <div validation-messages>\r\n <ng-content></ng-content>\r\n </div>\r\n </spx-input-box>", dependencies: [{ kind: "component", type: SpxInputBoxComponent, selector: "spx-input-box", inputs: ["spxCompact", "spxLabel", "spxReadonly", "spxRequired", "spxShowClear", "spxShowEdit", "spxShowHelp", "spxShowLabel", "spxShowSearch", "spxShowValidationMessages", "spxValue"], outputs: ["spxValueChange", "spxClear", "spxSearch", "spxEdit", "spxHelp", "spxSetIdInParent"] }, { kind: "component", type: SpxInputDateComponent, selector: "spx-input-date", inputs: ["spxMax", "spxMin", "spxReadonly", "spxValidators", "spxAutoFocus", "value", "spxSelectDay", "spxSelectMonth", "spxElementId", "spxSuggestions"], outputs: ["valueChange"] }, { kind: "component", type: SpxInputFloatComponent, selector: "spx-input-float", inputs: ["spxName", "spxAutofocus", "spxElementId", "spxReadonly", "spxValidators", "spxStep", "value", "spxWasInternalUpdate"], outputs: ["valueChange"] }, { kind: "component", type: SpxInputNumberComponent, selector: "spx-input-number", inputs: ["spxName", "spxAutofocus", "spxInputMode", "spxReadonly", "spxValidators", "spxFocused", "spxStep", "value", "spxElementId"], outputs: ["valueChange"] }, { kind: "component", type: SpxInputRadioComponent, selector: "spx-input-radio", inputs: ["spxName", "spxValidators", "spxShowLabel", "spxReadonly", "spxSuggestions", "value", "spxElementId"], outputs: ["valueChange"] }, { kind: "component", type: SpxInputTextComponent, selector: "spx-input-text", inputs: ["spxName", "spxAutofocus", "spxAutocomplete", "spxInputMode", "spxPattern", "spxSuggestions", "spxReadonly", "spxValidators", "spxCapitalize", "spxType", "spxWasInternalUpdate", "value", "spxElementId"], outputs: ["spxBlurFromChild", "valueChange"] }, { kind: "component", type: SpxInputTimeComponent, selector: "spx-input-time", inputs: ["spxName", "spxAutofocus", "spxInputMode", "spxPattern", "spxSuggestions", "spxReadonly", "spxValidators", "spxCapitalize", "value"], outputs: ["valueChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
1591
942
  }
1592
943
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: SpxInputComponent, decorators: [{
1593
944
  type: Component,
1594
- args: [{
1595
- selector: 'spx-input',
1596
- host: {
945
+ args: [{ selector: 'spx-input', host: {
1597
946
  '(spxChange)': 'handleChangeEvent($event)'
1598
- },
1599
- imports: [
947
+ }, imports: [
1600
948
  SpxInputBoxComponent,
1601
949
  SpxInputDateComponent,
1602
950
  SpxInputFloatComponent,
@@ -1604,207 +952,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImpor
1604
952
  SpxInputRadioComponent,
1605
953
  SpxInputTextComponent,
1606
954
  SpxInputTimeComponent
1607
- ],
1608
- providers: [
955
+ ], providers: [
1609
956
  {
1610
957
  provide: NG_VALUE_ACCESSOR,
1611
958
  useExisting: SpxInputComponent,
1612
959
  multi: true
1613
960
  }
1614
- ],
1615
- template: `<spx-input-box
1616
- [spxFocused]="this.spxFocused"
1617
- [spxLabel]="this.spxLabel"
1618
- [spxReadonly]="this.spxReadonly"
1619
- [spxRequired]="this.spxRequired"
1620
- [spxValue]="this.value"
1621
- [spxShowHelp]="this.spxShowHelp"
1622
- [spxCompact]="this.spxCompact"
1623
- [spxShowClear]="this.spxShowClear"
1624
- [spxShowEdit]="this.spxShowEdit"
1625
- [spxShowLabel]="this.spxShowLabel"
1626
- [spxShowSearch]="this.spxShowSearch ? this.spxShowSearch : this.spxType === 'autocomplete'"
1627
- [spxShowValidationMessages]="this.spxShowValidationMessages"
1628
- (spxClear)="this.handleClear()"
1629
- (spxEdit)="this.handleEdit()"
1630
- (spxHelp)="this.handleHelp()"
1631
- (spxFocus)="this.setFocusIn()"
1632
- (spxFocusOut)="this.setFocusOut()"
1633
- (spxSearch)="this.handleSearch()">
1634
- <div controls>
1635
- @if (this.spxType === 'autocomplete' || this.spxType === 'overlay' || this.spxType === 'overlaynumber' || this.spxType === 'text' || this.spxType === 'password') {
1636
- <spx-input-text
1637
- (spxBlurFromChild)="this.handleBlur()"
1638
- (spxChange)="this.handleChange($event)"
1639
- (spxFocus)="this.handleFocus()"
1640
- [spxAutocomplete]="this.spxAutocomplete ? this.spxAutocomplete : undefined"
1641
- [spxAutofocus]="this.spxAutofocus"
1642
- [spxCapitalize]="this.spxCapitalize"
1643
- [spxFocused]="this.spxFocused"
1644
- [spxInputMode]="this.spxType === 'overlaynumber' ? 'numeric' : this.spxInputMode"
1645
- [spxName]="this.spxName"
1646
- [spxPattern]="this.spxType === 'overlaynumber' ? '[0-9]*' : this.spxPattern"
1647
- [spxReadonly]="this.spxReadonly"
1648
- [spxSuggestions]="this.spxSuggestions"
1649
- [spxType]="this.spxType"
1650
- [spxValidators]="this.spxValidators"
1651
- [value]="this.value"
1652
- ></spx-input-text>
1653
- }
1654
- @if (this.spxType === 'date') {
1655
- <spx-input-date
1656
- (spxChange)="this.handleChange($event)"
1657
- (spxFocus)="this.handleFocus()"
1658
- [spxFocused]="this.spxFocused"
1659
- [spxMax]="this.spxMax!"
1660
- [spxMin]="this.spxMin!"
1661
- [spxReadonly]="this.spxReadonly"
1662
- [spxSelectDay]="this.spxSelectDay"
1663
- [spxSelectMonth]="this.spxSelectMonth"
1664
- [spxValidators]="this.spxValidators"
1665
- [(value)]="this.value"
1666
- ></spx-input-date>
1667
- }
1668
- @if (this.spxType === 'float') {
1669
- <spx-input-float
1670
- (spxChange)="this.handleChange($event)"
1671
- (spxFocus)="this.handleFocus()"
1672
- [spxAutofocus]="this.spxAutofocus"
1673
- [spxFocused]="this.spxFocused"
1674
- [spxName]="this.spxName"
1675
- [spxReadonly]="this.spxReadonly"
1676
- [spxStep]="this.spxStep"
1677
- [spxValidators]="this.spxValidators"
1678
- [value]="this.value"
1679
- ></spx-input-float>
1680
- }
1681
- @if (this.spxType === 'number') {
1682
- <spx-input-number
1683
- (spxChange)="this.handleChange($event)"
1684
- (spxFocus)="this.handleFocus()"
1685
- [spxAutofocus]="this.spxAutofocus"
1686
- [spxFocused]="this.spxFocused"
1687
- [spxInputMode]="this.spxInputMode"
1688
- [spxName]="this.spxName"
1689
- [spxReadonly]="this.spxReadonly"
1690
- [spxStep]="this.spxStep"
1691
- [spxValidators]="this.spxValidators"
1692
- [value]="this.value"
1693
- ></spx-input-number>
1694
- }
1695
- @if (this.spxType === 'radio') {
1696
- <spx-input-radio
1697
- #radioInput
1698
- (spxChange)="this.handleChange($event)"
1699
- [spxFocused]="this.spxFocused"
1700
- [spxName]="this.spxName"
1701
- [spxReadonly]="this.spxReadonly"
1702
- [spxShowLabel]="this.spxShowLabel"
1703
- [spxSuggestions]="this.spxSuggestions"
1704
- [spxValidators]="this.spxValidators"
1705
- [value]="this.value"
1706
- ></spx-input-radio>
1707
- }
1708
- @if (this.spxType === 'time') {
1709
- <spx-input-time
1710
- #timeInput
1711
- (spxChange)="this.handleChange($event)"
1712
- (spxFocus)="this.handleFocus()"
1713
- [spxFocused]="this.spxFocused"
1714
- [spxName]="this.spxName"
1715
- [spxReadonly]="this.spxReadonly"
1716
- [spxValidators]="this.spxValidators"
1717
- [value]="this.value"
1718
- ></spx-input-time>
1719
- }
1720
- </div>
1721
- <div validation-messages>
1722
- <ng-content></ng-content>
1723
- </div>
1724
- </spx-input-box>`
1725
- }]
1726
- }], propDecorators: { spxLabel: [{
1727
- type: Input
1728
- }], spxMax: [{
1729
- type: Input
1730
- }], spxMin: [{
1731
- type: Input
1732
- }], spxName: [{
1733
- type: Input
1734
- }], spxReadonly: [{
1735
- type: Input
1736
- }], spxAutocomplete: [{
1737
- type: Input
1738
- }], spxAutofocus: [{
1739
- type: Input
1740
- }], spxInputMode: [{
1741
- type: Input
1742
- }], spxPattern: [{
1743
- type: Input
1744
- }], spxRequired: [{
1745
- type: Input
1746
- }], spxSelectMonth: [{
1747
- type: Input
1748
- }], spxSelectDay: [{
1749
- type: Input
1750
- }], spxShowEdit: [{
1751
- type: Input
1752
- }], spxShowHelp: [{
1753
- type: Input
1754
- }], spxShowLabel: [{
1755
- type: Input
1756
- }], spxCompact: [{
1757
- type: Input
1758
- }], spxShowClear: [{
1759
- type: Input
1760
- }], spxShowSearch: [{
1761
- type: Input
1762
- }], spxShowValidationMessages: [{
1763
- type: Input
1764
- }], spxStep: [{
1765
- type: Input
1766
- }], spxSuggestions: [{
1767
- type: Input
1768
- }], spxType: [{
1769
- type: Input
1770
- }], spxValidators: [{
1771
- type: Input
1772
- }], value: [{
1773
- type: Input
1774
- }], spxCapitalize: [{
1775
- type: Input
1776
- }], spxBlur: [{
1777
- type: Output
1778
- }], spxClear: [{
1779
- type: Output
1780
- }], spxChange: [{
1781
- type: Output
1782
- }], spxFocus: [{
1783
- type: Output
1784
- }], spxEdit: [{
1785
- type: Output
1786
- }], spxHelp: [{
1787
- type: Output
1788
- }], spxSearch: [{
1789
- type: Output
1790
- }], floatInput: [{
1791
- type: ViewChild,
1792
- args: [SpxInputFloatComponent]
1793
- }], numberInput: [{
1794
- type: ViewChild,
1795
- args: [SpxInputNumberComponent]
1796
- }], textInput: [{
1797
- type: ViewChild,
1798
- args: [SpxInputTextComponent]
1799
- }], timeInput: [{
1800
- type: ViewChild,
1801
- args: [SpxInputTimeComponent]
1802
- }], radioInput: [{
1803
- type: ViewChild,
1804
- args: [SpxInputRadioComponent]
1805
- }], spxFocused: [{
1806
- type: Input
1807
- }], _handleBlurEvent: [{
961
+ ], standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, template: "<spx-input-box\r\n [spxLabel]=\"this.spxLabel()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxRequired]=\"this.spxRequired()\"\r\n [spxValue]=\"this.value()\"\r\n [spxShowHelp]=\"this.spxShowHelp()\"\r\n [spxCompact]=\"this.spxCompact()\"\r\n [spxShowClear]=\"this.spxShowClear()\"\r\n [spxShowEdit]=\"this.spxShowEdit()\"\r\n [spxShowLabel]=\"this.spxShowLabel()\"\r\n [spxShowSearch]=\"this.spxShowSearch() ? this.spxShowSearch() : this.spxType() === 'autocomplete'\"\r\n [spxShowValidationMessages]=\"this.spxShowValidationMessages()\"\r\n (spxClear)=\"this.handleClear()\"\r\n (spxEdit)=\"this.handleEdit()\"\r\n (spxHelp)=\"this.handleHelp()\"\r\n (spxSearch)=\"this.handleSearch()\"\r\n (spxSetIdInParent)=\"handleSpxElementIdSet($event)\"\r\n >\r\n <div controls>\r\n @if (this.spxType() === 'autocomplete' || this.spxType() === 'overlay' || this.spxType() === 'overlaynumber' || this.spxType() === 'text' || this.spxType() === 'password') {\r\n <spx-input-text #spxInputText\r\n [spxAutocomplete]=\"this.spxAutocomplete() ? this.spxAutocomplete() : undefined\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxCapitalize]=\"this.spxCapitalize()\"\r\n [spxInputMode]=\"this.spxType() === 'overlaynumber' ? 'numeric' : this.spxInputMode()\"\r\n [spxName]=\"this.spxName()\"\r\n [spxPattern]=\"this.spxType() === 'overlaynumber' ? '[0-9]*' : this.spxPattern()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxSuggestions]=\"this.spxSuggestions()\"\r\n [spxType]=\"this.spxType()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-text>\r\n }\r\n @if (this.spxType() === 'date') {\r\n <spx-input-date #spxInputDate\r\n [spxMax]=\"this.spxMax()!\"\r\n [spxMin]=\"this.spxMin()!\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxSelectDay]=\"this.spxSelectDay()\"\r\n [spxSelectMonth]=\"this.spxSelectMonth()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [spxAutoFocus]=\"this.spxAutofocus()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-date>\r\n }\r\n @if (this.spxType() === 'float') {\r\n <spx-input-float #spxInputFloat\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxStep]=\"this.spxStep()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-float>\r\n }\r\n @if (this.spxType() === 'number') {\r\n <spx-input-number #spxInputNumber\r\n [spxInputMode]=\"this.spxInputMode()\"\r\n [spxAutofocus]=\"this.spxAutofocus()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxStep]=\"this.spxStep()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-number>\r\n }\r\n @if (this.spxType() === 'radio') {\r\n <spx-input-radio\r\n #spxInputRadio\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxShowLabel]=\"this.spxShowLabel()\"\r\n [spxSuggestions]=\"this.spxSuggestions()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [spxElementId]=\"this.spxElementId()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-radio>\r\n }\r\n @if (this.spxType() === 'time') {\r\n <spx-input-time\r\n #spxInputTime\r\n [spxName]=\"this.spxName()\"\r\n [spxReadonly]=\"this.spxReadonly()\"\r\n [spxValidators]=\"this.spxValidators()\"\r\n [value]=\"value()\"\r\n (valueChange)=\"handleChangeEvent($event)\"\r\n ></spx-input-time>\r\n }\r\n </div>\r\n <div validation-messages>\r\n <ng-content></ng-content>\r\n </div>\r\n </spx-input-box>" }]
962
+ }], propDecorators: { _handleBlurEvent: [{
1808
963
  type: HostListener,
1809
964
  args: ['focusout']
1810
965
  }] } });