@ngil/form-inputs 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +9 -0
  2. package/esm2022/index.mjs +11 -0
  3. package/esm2022/lib/components/input/input.component.mjs +55 -0
  4. package/esm2022/lib/components/overlay/overlay-toggle.directive.mjs +57 -0
  5. package/esm2022/lib/components/overlay/overlay.component.mjs +106 -0
  6. package/esm2022/lib/components/select/select.component.mjs +69 -0
  7. package/esm2022/lib/components/select-options/select-options.component.mjs +58 -0
  8. package/esm2022/lib/components/textarea/textarea.component.mjs +45 -0
  9. package/esm2022/lib/components/time-picker/time-picker.component.mjs +65 -0
  10. package/esm2022/lib/components/time-picker/time-picker.directive.mjs +114 -0
  11. package/esm2022/lib/components/time-picker/time-picker.model.mjs +2 -0
  12. package/esm2022/lib/components/time-picker-overlay/picker-toggle.mjs +24 -0
  13. package/esm2022/lib/components/time-picker-overlay/time-picker-overlay.component.mjs +114 -0
  14. package/esm2022/lib/directives/number-rotation.directive.mjs +102 -0
  15. package/esm2022/lib/ngil-ui-form.module.mjs +68 -0
  16. package/esm2022/ngil-form-inputs.mjs +5 -0
  17. package/fesm2022/ngil-form-inputs.mjs +813 -0
  18. package/fesm2022/ngil-form-inputs.mjs.map +1 -0
  19. package/index.d.ts +10 -0
  20. package/lib/components/input/input.component.d.ts +14 -0
  21. package/lib/components/overlay/overlay-toggle.directive.d.ts +16 -0
  22. package/lib/components/overlay/overlay.component.d.ts +22 -0
  23. package/lib/components/select/select.component.d.ts +16 -0
  24. package/lib/components/select-options/select-options.component.d.ts +17 -0
  25. package/lib/components/textarea/textarea.component.d.ts +12 -0
  26. package/lib/components/time-picker/time-picker.component.d.ts +19 -0
  27. package/lib/components/time-picker/time-picker.directive.d.ts +28 -0
  28. package/lib/components/time-picker/time-picker.model.d.ts +5 -0
  29. package/lib/components/time-picker-overlay/picker-toggle.d.ts +8 -0
  30. package/lib/components/time-picker-overlay/time-picker-overlay.component.d.ts +26 -0
  31. package/lib/directives/number-rotation.directive.d.ts +26 -0
  32. package/lib/ngil-ui-form.module.d.ts +20 -0
  33. package/package.json +32 -0
@@ -0,0 +1,813 @@
1
+ import * as i0 from '@angular/core';
2
+ import { EventEmitter, forwardRef, Component, ChangeDetectionStrategy, Input, Output, ViewEncapsulation, ViewChild, Directive, HostListener, Optional, NgModule } from '@angular/core';
3
+ import * as i2 from '@angular/forms';
4
+ import { FormControl, NG_VALUE_ACCESSOR, FormGroup, ReactiveFormsModule } from '@angular/forms';
5
+ import { AbstractInputComponent } from '@ngil/form-cva';
6
+ import { takeUntil } from 'rxjs/operators';
7
+ import * as i1 from '@angular/common';
8
+ import { CommonModule } from '@angular/common';
9
+ import * as i1$1 from '@angular/cdk/overlay';
10
+ import { OverlayModule } from '@angular/cdk/overlay';
11
+ import { DomPortal, ComponentPortal } from '@angular/cdk/portal';
12
+ import { Subject, takeUntil as takeUntil$1 } from 'rxjs';
13
+
14
+ class NgilInputComponent extends AbstractInputComponent {
15
+ constructor() {
16
+ super(...arguments);
17
+ this.type = 'text';
18
+ this.changed = new EventEmitter();
19
+ this.control = new FormControl();
20
+ }
21
+ ngAfterViewInit() {
22
+ this.control.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
23
+ this.onChangeInput(value);
24
+ });
25
+ }
26
+ writeValue(value) {
27
+ this.control.setValue(value);
28
+ }
29
+ onChangeInput(value) {
30
+ if (this.type === 'number') {
31
+ value = +value;
32
+ }
33
+ this.changed.emit(value);
34
+ if (this.onChange) {
35
+ this.onChange(value);
36
+ }
37
+ }
38
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilInputComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
39
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilInputComponent, selector: "ngil-input", inputs: { type: "type" }, outputs: { changed: "changed" }, providers: [
40
+ {
41
+ provide: NG_VALUE_ACCESSOR,
42
+ useExisting: forwardRef(() => NgilInputComponent),
43
+ multi: true
44
+ }
45
+ ], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-input\" [class.ngil-input--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-input__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-input__field\">\r\n <input\r\n class=\"ngil-input__input\"\r\n [id]=\"formControlName\"\r\n [required]=\"required\"\r\n [readonly]=\"readonly\"\r\n [type]=\"type\"\r\n [formControl]=\"control\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-input__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-input{flex-grow:1;position:relative}:host .ngil-input--error{color:red}:host .ngil-input--error .ngil-input__input{border-color:red}:host .ngil-input__label{display:block}:host .ngil-input__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem}:host .ngil-input__field{display:flex}:host .ngil-input__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
46
+ }
47
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilInputComponent, decorators: [{
48
+ type: Component,
49
+ args: [{ selector: 'ngil-input', providers: [
50
+ {
51
+ provide: NG_VALUE_ACCESSOR,
52
+ useExisting: forwardRef(() => NgilInputComponent),
53
+ multi: true
54
+ }
55
+ ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-input\" [class.ngil-input--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-input__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-input__field\">\r\n <input\r\n class=\"ngil-input__input\"\r\n [id]=\"formControlName\"\r\n [required]=\"required\"\r\n [readonly]=\"readonly\"\r\n [type]=\"type\"\r\n [formControl]=\"control\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-input__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-input{flex-grow:1;position:relative}:host .ngil-input--error{color:red}:host .ngil-input--error .ngil-input__input{border-color:red}:host .ngil-input__label{display:block}:host .ngil-input__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem}:host .ngil-input__field{display:flex}:host .ngil-input__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}\n"] }]
56
+ }], propDecorators: { type: [{
57
+ type: Input
58
+ }], changed: [{
59
+ type: Output
60
+ }] } });
61
+
62
+ class NgilOverlayComponent {
63
+ constructor(overlay) {
64
+ this.overlay = overlay;
65
+ this.overwriteConfig = {};
66
+ this.destroy$ = new Subject();
67
+ this.maxHeight = 500;
68
+ this.isOpened = false;
69
+ }
70
+ open() {
71
+ this.overlayRef = this.overlay.create(this.getOverlayConfig());
72
+ const portal = new DomPortal(this.el);
73
+ this.overlayRef.attach(portal);
74
+ this.overlayRef
75
+ .backdropClick()
76
+ .pipe(takeUntil$1(this.destroy$))
77
+ .subscribe(() => {
78
+ this.close();
79
+ });
80
+ this.isOpened = true;
81
+ }
82
+ getOverlayConfig() {
83
+ return {
84
+ positionStrategy: this.getStrategy(),
85
+ hasBackdrop: true,
86
+ backdropClass: this.origin ? 'cdk-overlay-transparent-backdrop' : 'cdk-overlay-dark-backdrop',
87
+ panelClass: ['ngil-overlay-panel'],
88
+ maxHeight: this.maxHeight,
89
+ minWidth: this.origin?.nativeElement.offsetWidth,
90
+ ...this.overwriteConfig
91
+ };
92
+ }
93
+ getStrategy() {
94
+ if (!this.origin) {
95
+ return this.overlay.position().global().centerHorizontally().centerVertically();
96
+ }
97
+ const primaryX = 'start';
98
+ const secondaryX = primaryX === 'start' ? 'end' : 'start';
99
+ const primaryY = 'top';
100
+ const secondaryY = 'bottom';
101
+ return this.overlay
102
+ .position()
103
+ .flexibleConnectedTo(this.origin)
104
+ .withPositions([
105
+ {
106
+ originX: primaryX,
107
+ originY: secondaryY,
108
+ overlayX: primaryX,
109
+ overlayY: primaryY
110
+ },
111
+ {
112
+ originX: primaryX,
113
+ originY: primaryY,
114
+ overlayX: primaryX,
115
+ overlayY: secondaryY
116
+ },
117
+ {
118
+ originX: secondaryX,
119
+ originY: secondaryY,
120
+ overlayX: secondaryX,
121
+ overlayY: primaryY
122
+ },
123
+ {
124
+ originX: secondaryX,
125
+ originY: primaryY,
126
+ overlayX: secondaryX,
127
+ overlayY: secondaryY
128
+ }
129
+ ]);
130
+ }
131
+ close() {
132
+ this.destroy$.next();
133
+ this.overlayRef?.dispose();
134
+ this.overlayRef = undefined;
135
+ this.isOpened = false;
136
+ }
137
+ toggle() {
138
+ if (this.isOpened) {
139
+ this.close();
140
+ }
141
+ else {
142
+ this.open();
143
+ }
144
+ }
145
+ ngOnDestroy() {
146
+ this.destroy$.next();
147
+ this.destroy$.complete();
148
+ }
149
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilOverlayComponent, deps: [{ token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
150
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilOverlayComponent, selector: "ngil-overlay", inputs: { overwriteConfig: "overwriteConfig" }, viewQueries: [{ propertyName: "el", first: true, predicate: ["contentWrapper"], descendants: true }], ngImport: i0, template: "<div class=\"ngil-overlay-content\" #contentWrapper>\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: ["ngil-overlay{display:none}.ngil-overlay-panel .ngil-overlay-content{display:flex;width:100%}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
151
+ }
152
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilOverlayComponent, decorators: [{
153
+ type: Component,
154
+ args: [{ selector: 'ngil-overlay', changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, template: "<div class=\"ngil-overlay-content\" #contentWrapper>\r\n <ng-content></ng-content>\r\n</div>\r\n", styles: ["ngil-overlay{display:none}.ngil-overlay-panel .ngil-overlay-content{display:flex;width:100%}\n"] }]
155
+ }], ctorParameters: () => [{ type: i1$1.Overlay }], propDecorators: { el: [{
156
+ type: ViewChild,
157
+ args: ['contentWrapper']
158
+ }], overwriteConfig: [{
159
+ type: Input
160
+ }] } });
161
+
162
+ class NgilSelectOptionsComponent {
163
+ constructor() {
164
+ this.selectedItems = null;
165
+ this.items = [];
166
+ this.multiple = false;
167
+ this.display = false;
168
+ this.itemSelected = new EventEmitter();
169
+ this.destroy$ = new Subject();
170
+ }
171
+ onItemSelected(item) {
172
+ let newSelection;
173
+ if (Array.isArray(this.selectedItems)) {
174
+ newSelection = this.selectedItems.includes(item)
175
+ ? this.selectedItems.filter(selectedItem => selectedItem !== item)
176
+ : [...this.selectedItems, item];
177
+ }
178
+ else if (this.multiple && this.selectedItems) {
179
+ newSelection = [this.selectedItems, item];
180
+ }
181
+ else {
182
+ newSelection = item;
183
+ }
184
+ this.itemSelected.emit(newSelection);
185
+ }
186
+ isSelected(item) {
187
+ if (Array.isArray(this.selectedItems)) {
188
+ return this.selectedItems.includes(item);
189
+ }
190
+ return item === this.selectedItems;
191
+ }
192
+ ngOnDestroy() {
193
+ this.destroy$.next();
194
+ this.destroy$.complete();
195
+ }
196
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilSelectOptionsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
197
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilSelectOptionsComponent, selector: "ngil-select-options", inputs: { selectedItems: "selectedItems", items: "items", displayKey: "displayKey", multiple: "multiple", display: "display" }, outputs: { itemSelected: "itemSelected" }, ngImport: i0, template: "<div class=\"ngil-dropdown\" *ngIf=\"display\" role=\"listbox\" data-test=\"ngil-select-options-list\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div\r\n role=\"option\"\r\n class=\"ngil-dropdown__item\"\r\n data-test=\"ngil-select-option\"\r\n [attr.value]=\"item\"\r\n [attr.displayValue]=\"displayKey ? item[displayKey] : item\"\r\n (click)=\"onItemSelected(item)\"\r\n [class.ngil-dropdown__item--selected]=\"isSelected(item)\"\r\n >\r\n {{ displayKey ? item[displayKey] : item }}\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;min-width:200px;background:#fff;border:1px solid #000;overflow-y:auto}:host .ngil-dropdown__item{line-height:1.5rem;padding:.25rem .5rem}:host .ngil-dropdown__item:hover{background:#d3d3d3}:host .ngil-dropdown__item--selected{background:#708090}\n"], dependencies: [{ kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
198
+ }
199
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilSelectOptionsComponent, decorators: [{
200
+ type: Component,
201
+ args: [{ selector: 'ngil-select-options', changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"ngil-dropdown\" *ngIf=\"display\" role=\"listbox\" data-test=\"ngil-select-options-list\">\r\n <ng-container *ngFor=\"let item of items\">\r\n <div\r\n role=\"option\"\r\n class=\"ngil-dropdown__item\"\r\n data-test=\"ngil-select-option\"\r\n [attr.value]=\"item\"\r\n [attr.displayValue]=\"displayKey ? item[displayKey] : item\"\r\n (click)=\"onItemSelected(item)\"\r\n [class.ngil-dropdown__item--selected]=\"isSelected(item)\"\r\n >\r\n {{ displayKey ? item[displayKey] : item }}\r\n </div>\r\n </ng-container>\r\n</div>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;min-width:200px;background:#fff;border:1px solid #000;overflow-y:auto}:host .ngil-dropdown__item{line-height:1.5rem;padding:.25rem .5rem}:host .ngil-dropdown__item:hover{background:#d3d3d3}:host .ngil-dropdown__item--selected{background:#708090}\n"] }]
202
+ }], propDecorators: { selectedItems: [{
203
+ type: Input
204
+ }], items: [{
205
+ type: Input
206
+ }], displayKey: [{
207
+ type: Input
208
+ }], multiple: [{
209
+ type: Input
210
+ }], display: [{
211
+ type: Input
212
+ }], itemSelected: [{
213
+ type: Output
214
+ }] } });
215
+
216
+ class OverlayToggleDirective {
217
+ set ngilOverlayToggle(overlay) {
218
+ this.overlay = overlay;
219
+ }
220
+ set isOverlayOrigin(isOrigin) {
221
+ this.isOrigin = isOrigin;
222
+ this.setOverlayOrigin();
223
+ }
224
+ constructor(elementRef) {
225
+ this.elementRef = elementRef;
226
+ this.isOrigin = true;
227
+ this.onClick = (event) => {
228
+ if (!this.overlay) {
229
+ throw new Error(`The overlay is not defined. The overlay component should be provided in the directive input
230
+
231
+ <my-element [ngilOverlayToggle]="overlay"></my-element>
232
+ <ngil-overlay #overlay>...</ngil-overlay>
233
+ `);
234
+ }
235
+ if (!this.overlay.isOpened) {
236
+ this.overlay.open();
237
+ }
238
+ event.stopPropagation();
239
+ };
240
+ }
241
+ ngOnInit() {
242
+ this.setOverlayOrigin();
243
+ }
244
+ setOverlayOrigin() {
245
+ if (this.isOrigin && this.overlay) {
246
+ this.overlay.origin = this.elementRef;
247
+ }
248
+ else if (this.overlay) {
249
+ this.overlay.origin = undefined;
250
+ }
251
+ }
252
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: OverlayToggleDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); }
253
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.2", type: OverlayToggleDirective, selector: "[ngilOverlayToggle]", inputs: { ngilOverlayToggle: "ngilOverlayToggle", isOverlayOrigin: "isOverlayOrigin" }, host: { listeners: { "click": "onClick($event)" } }, exportAs: ["ngilOverlayToggle"], ngImport: i0 }); }
254
+ }
255
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: OverlayToggleDirective, decorators: [{
256
+ type: Directive,
257
+ args: [{
258
+ selector: '[ngilOverlayToggle]',
259
+ exportAs: 'ngilOverlayToggle'
260
+ }]
261
+ }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { ngilOverlayToggle: [{
262
+ type: Input
263
+ }], isOverlayOrigin: [{
264
+ type: Input
265
+ }], onClick: [{
266
+ type: HostListener,
267
+ args: ['click', ['$event']]
268
+ }] } });
269
+
270
+ class NgilSelectComponent extends AbstractInputComponent {
271
+ constructor() {
272
+ super(...arguments);
273
+ this.multiple = false;
274
+ this.items = [];
275
+ this.value = null;
276
+ }
277
+ get displayValue() {
278
+ if (Array.isArray(this.value)) {
279
+ return this.value.map(item => (this.displayKey ? item[this.displayKey] : item)).join(',');
280
+ }
281
+ if (this.value && this.displayKey) {
282
+ return this.value[this.displayKey];
283
+ }
284
+ return this.value;
285
+ }
286
+ writeValue(value) {
287
+ this.value = value;
288
+ }
289
+ onItemSelected(item) {
290
+ this.value = item;
291
+ if (!this.multiple) {
292
+ this.overlay?.close();
293
+ }
294
+ if (this.onChange) {
295
+ this.onChange(this.value);
296
+ }
297
+ }
298
+ isArray(item) {
299
+ return Array.isArray(item);
300
+ }
301
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilSelectComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
302
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilSelectComponent, selector: "ngil-select", inputs: { multiple: "multiple", items: "items", displayKey: "displayKey" }, providers: [
303
+ {
304
+ provide: NG_VALUE_ACCESSOR,
305
+ useExisting: forwardRef(() => NgilSelectComponent),
306
+ multi: true
307
+ }
308
+ ], viewQueries: [{ propertyName: "overlay", first: true, predicate: NgilOverlayComponent, descendants: true }], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-select\" [class.ngil-select--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-select__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-select__field\">\r\n <div class=\"ngil-select__field-content\">\r\n <input\r\n class=\"ngil-select__input\"\r\n [value]=\"displayValue\"\r\n [disabled]=\"disabled\"\r\n (keydown)=\"$event.preventDefault(); overlay.toggle()\"\r\n [id]=\"formControlName\"\r\n (blur)=\"onBlur()\"\r\n [ngilOverlayToggle]=\"overlay\"\r\n />\r\n </div>\r\n\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-select__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n\r\n <ngil-overlay #overlay>\r\n <ngil-select-options\r\n ngilOverlay\r\n class=\"ngil-select__dropdown\"\r\n data-test=\"ngil-select-options\"\r\n [display]=\"overlay.isOpened\"\r\n [multiple]=\"multiple\"\r\n [items]=\"items\"\r\n [displayKey]=\"displayKey\"\r\n [selectedItems]=\"value\"\r\n (itemSelected)=\"onItemSelected($event)\"\r\n ></ngil-select-options>\r\n </ngil-overlay>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-select{flex-grow:1;position:relative}:host .ngil-select--error{color:red}:host .ngil-select--error .ngil-select__input{border-color:red}:host .ngil-select__label{display:block}:host .ngil-select__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem;overflow:hidden}:host .ngil-select__field{display:flex}:host .ngil-select__field-content{flex-grow:1}:host .ngil-select__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}:host .ngil-select__dropdown{width:100%}:host .hidden{display:none}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: NgilSelectOptionsComponent, selector: "ngil-select-options", inputs: ["selectedItems", "items", "displayKey", "multiple", "display"], outputs: ["itemSelected"] }, { kind: "component", type: NgilOverlayComponent, selector: "ngil-overlay", inputs: ["overwriteConfig"] }, { kind: "directive", type: OverlayToggleDirective, selector: "[ngilOverlayToggle]", inputs: ["ngilOverlayToggle", "isOverlayOrigin"], exportAs: ["ngilOverlayToggle"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
309
+ }
310
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilSelectComponent, decorators: [{
311
+ type: Component,
312
+ args: [{ selector: 'ngil-select', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
313
+ {
314
+ provide: NG_VALUE_ACCESSOR,
315
+ useExisting: forwardRef(() => NgilSelectComponent),
316
+ multi: true
317
+ }
318
+ ], template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-select\" [class.ngil-select--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-select__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-select__field\">\r\n <div class=\"ngil-select__field-content\">\r\n <input\r\n class=\"ngil-select__input\"\r\n [value]=\"displayValue\"\r\n [disabled]=\"disabled\"\r\n (keydown)=\"$event.preventDefault(); overlay.toggle()\"\r\n [id]=\"formControlName\"\r\n (blur)=\"onBlur()\"\r\n [ngilOverlayToggle]=\"overlay\"\r\n />\r\n </div>\r\n\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-select__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n\r\n <ngil-overlay #overlay>\r\n <ngil-select-options\r\n ngilOverlay\r\n class=\"ngil-select__dropdown\"\r\n data-test=\"ngil-select-options\"\r\n [display]=\"overlay.isOpened\"\r\n [multiple]=\"multiple\"\r\n [items]=\"items\"\r\n [displayKey]=\"displayKey\"\r\n [selectedItems]=\"value\"\r\n (itemSelected)=\"onItemSelected($event)\"\r\n ></ngil-select-options>\r\n </ngil-overlay>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-select{flex-grow:1;position:relative}:host .ngil-select--error{color:red}:host .ngil-select--error .ngil-select__input{border-color:red}:host .ngil-select__label{display:block}:host .ngil-select__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem;overflow:hidden}:host .ngil-select__field{display:flex}:host .ngil-select__field-content{flex-grow:1}:host .ngil-select__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}:host .ngil-select__dropdown{width:100%}:host .hidden{display:none}\n"] }]
319
+ }], propDecorators: { overlay: [{
320
+ type: ViewChild,
321
+ args: [NgilOverlayComponent]
322
+ }], multiple: [{
323
+ type: Input
324
+ }], items: [{
325
+ type: Input
326
+ }], displayKey: [{
327
+ type: Input
328
+ }] } });
329
+
330
+ class NgilTextareaComponent extends AbstractInputComponent {
331
+ constructor() {
332
+ super(...arguments);
333
+ this.control = new FormControl();
334
+ }
335
+ ngAfterViewInit() {
336
+ this.control.valueChanges.pipe(takeUntil$1(this.destroy$)).subscribe(value => {
337
+ this.onChangeInput(value);
338
+ });
339
+ }
340
+ writeValue(value) {
341
+ this.control.setValue(value);
342
+ }
343
+ onChangeInput(value) {
344
+ if (this.onChange) {
345
+ this.onChange(value);
346
+ }
347
+ }
348
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTextareaComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
349
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilTextareaComponent, selector: "ngil-textarea", providers: [
350
+ {
351
+ provide: NG_VALUE_ACCESSOR,
352
+ useExisting: forwardRef(() => NgilTextareaComponent),
353
+ multi: true
354
+ }
355
+ ], usesInheritance: true, ngImport: i0, template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-textarea\" [class.ngil-textarea--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-textarea__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-textarea__field\">\r\n <textarea\r\n class=\"ngil-textarea__input\"\r\n [id]=\"formControlName\"\r\n [required]=\"required\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"control\"\r\n (blur)=\"onBlur()\"\r\n >\r\n </textarea>\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-textarea__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-textarea{flex-grow:1;position:relative}:host .ngil-textarea--error{color:red}:host .ngil-textarea--error .ngil-textarea__input{border-color:red}:host .ngil-textarea__label{display:block}:host .ngil-textarea__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem;height:4rem}:host .ngil-textarea__field{display:flex}:host .ngil-textarea__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.RequiredValidator, selector: ":not([type=checkbox])[required][formControlName],:not([type=checkbox])[required][formControl],:not([type=checkbox])[required][ngModel]", inputs: ["required"] }, { kind: "directive", type: i2.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
356
+ }
357
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTextareaComponent, decorators: [{
358
+ type: Component,
359
+ args: [{ selector: 'ngil-textarea', changeDetection: ChangeDetectionStrategy.OnPush, providers: [
360
+ {
361
+ provide: NG_VALUE_ACCESSOR,
362
+ useExisting: forwardRef(() => NgilTextareaComponent),
363
+ multi: true
364
+ }
365
+ ], template: "<ng-container *ngIf=\"model$ | async as model\">\r\n <div class=\"ngil-textarea\" [class.ngil-textarea--error]=\"!!model.errorMessage\">\r\n <label class=\"ngil-textarea__label\" [for]=\"formControlName\">{{ label }}{{ required ? '*' : '' }}</label>\r\n\r\n <div class=\"ngil-textarea__field\">\r\n <textarea\r\n class=\"ngil-textarea__input\"\r\n [id]=\"formControlName\"\r\n [required]=\"required\"\r\n [readonly]=\"readonly\"\r\n [formControl]=\"control\"\r\n (blur)=\"onBlur()\"\r\n >\r\n </textarea>\r\n <ng-content select=\"[suffix]\"></ng-content>\r\n </div>\r\n\r\n <small class=\"ngil-textarea__error-message\">{{ model.errorMessage }}</small>\r\n </div>\r\n</ng-container>\r\n", styles: [":host{display:flex;width:100%;flex-direction:column;margin:.25rem 0 2rem;min-width:200px}:host .ngil-textarea{flex-grow:1;position:relative}:host .ngil-textarea--error{color:red}:host .ngil-textarea--error .ngil-textarea__input{border-color:red}:host .ngil-textarea__label{display:block}:host .ngil-textarea__input{width:100%;outline:none;border:1px solid black;border-radius:3px;padding:.25rem;height:4rem}:host .ngil-textarea__field{display:flex}:host .ngil-textarea__error-message{position:absolute;margin:.1rem 0;height:1rem;font-size:85%}\n"] }]
366
+ }] });
367
+
368
+ class PickerToggleComponent {
369
+ constructor() {
370
+ this.onClick = (event) => {
371
+ if (!this.picker?.isOpen) {
372
+ this.picker?.open();
373
+ }
374
+ event.stopPropagation();
375
+ };
376
+ }
377
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: PickerToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
378
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: PickerToggleComponent, selector: "ngil-picker-toggle", inputs: { picker: "picker" }, host: { listeners: { "click": "onClick($event)" } }, ngImport: i0, template: "<button class=\"toggle-button\" type=\"button\">\r\n <svg\r\n class=\"mat-datepicker-toggle-default-icon\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"24px\"\r\n height=\"24px\"\r\n fill=\"currentColor\"\r\n focusable=\"false\"\r\n >\r\n <path\r\n d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"\r\n />\r\n </svg>\r\n</button>\r\n", styles: [".toggle-button{background:none;border:none}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
379
+ }
380
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: PickerToggleComponent, decorators: [{
381
+ type: Component,
382
+ args: [{ selector: 'ngil-picker-toggle', encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, template: "<button class=\"toggle-button\" type=\"button\">\r\n <svg\r\n class=\"mat-datepicker-toggle-default-icon\"\r\n viewBox=\"0 0 24 24\"\r\n width=\"24px\"\r\n height=\"24px\"\r\n fill=\"currentColor\"\r\n focusable=\"false\"\r\n >\r\n <path\r\n d=\"M19 3h-1V1h-2v2H8V1H6v2H5c-1.11 0-1.99.9-1.99 2L3 19c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2zm0 16H5V8h14v11zM7 10h5v5H7z\"\r\n />\r\n </svg>\r\n</button>\r\n", styles: [".toggle-button{background:none;border:none}\n"] }]
383
+ }], propDecorators: { picker: [{
384
+ type: Input
385
+ }], onClick: [{
386
+ type: HostListener,
387
+ args: ['click', ['$event']]
388
+ }] } });
389
+
390
+ class NumberRotationDirective {
391
+ get length() {
392
+ return this.max.toString().length;
393
+ }
394
+ constructor(elementRef, ngControl) {
395
+ this.elementRef = elementRef;
396
+ this.ngControl = ngControl;
397
+ this.min = 0;
398
+ this.max = 10;
399
+ this.onKeyDown = (event) => {
400
+ this.onKeyDownEvent(event);
401
+ };
402
+ this.onInput = (event) => {
403
+ let value = event.target.value;
404
+ if (+value > this.max) {
405
+ value = value.slice(this.length);
406
+ }
407
+ this.setValue(+value);
408
+ };
409
+ this.onUp = () => {
410
+ const value = +this.elementRef.nativeElement.value;
411
+ this.setValue(value + 1);
412
+ };
413
+ this.onDown = () => {
414
+ const value = +this.elementRef.nativeElement.value;
415
+ this.setValue(value - 1);
416
+ };
417
+ }
418
+ ngOnInit() {
419
+ this.elementRef.nativeElement.value = this.elementRef.nativeElement.value.toString().padStart(this.length, '0');
420
+ }
421
+ ngAfterViewInit() {
422
+ this.buttonUp?.addEventListener('click', this.onUp);
423
+ this.buttonDown?.addEventListener('click', this.onDown);
424
+ }
425
+ onKeyDownEvent(event) {
426
+ if (!this.isKeyValid(event.key)) {
427
+ event.preventDefault();
428
+ return;
429
+ }
430
+ if (event.key === 'ArrowUp') {
431
+ event.preventDefault();
432
+ this.onUp();
433
+ }
434
+ if (event.key === 'ArrowDown') {
435
+ event.preventDefault();
436
+ this.onDown();
437
+ }
438
+ }
439
+ isKeyValid(key) {
440
+ if (key.length !== 1 || !isNaN(+key)) {
441
+ return true;
442
+ }
443
+ return false;
444
+ }
445
+ setValue(value) {
446
+ if (value < this.min) {
447
+ this.setInputValue(this.max);
448
+ }
449
+ else if (value > this.max) {
450
+ this.setInputValue(this.min);
451
+ }
452
+ else {
453
+ this.setInputValue(value);
454
+ }
455
+ }
456
+ setInputValue(value) {
457
+ this.ngControl.control?.setValue(value);
458
+ this.elementRef.nativeElement.value = value.toString().padStart(this.length, '0');
459
+ }
460
+ ngOnDestroy() {
461
+ this.buttonUp?.removeEventListener('click', this.onUp);
462
+ this.buttonDown?.removeEventListener('click', this.onDown);
463
+ }
464
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NumberRotationDirective, deps: [{ token: i0.ElementRef }, { token: i2.NgControl }], target: i0.ɵɵFactoryTarget.Directive }); }
465
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.2", type: NumberRotationDirective, selector: "input[ngilNumberRotation]", inputs: { min: "min", max: "max", buttonUp: "buttonUp", buttonDown: "buttonDown" }, host: { listeners: { "keydown": "onKeyDown($event)", "input": "onInput($event)" } }, ngImport: i0 }); }
466
+ }
467
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NumberRotationDirective, decorators: [{
468
+ type: Directive,
469
+ args: [{
470
+ selector: 'input[ngilNumberRotation]'
471
+ }]
472
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: i2.NgControl }], propDecorators: { min: [{
473
+ type: Input
474
+ }], max: [{
475
+ type: Input
476
+ }], buttonUp: [{
477
+ type: Input
478
+ }], buttonDown: [{
479
+ type: Input
480
+ }], onKeyDown: [{
481
+ type: HostListener,
482
+ args: ['keydown', ['$event']]
483
+ }], onInput: [{
484
+ type: HostListener,
485
+ args: ['input', ['$event']]
486
+ }] } });
487
+
488
+ class NgilTimePickerComponent extends AbstractInputComponent {
489
+ constructor() {
490
+ super(...arguments);
491
+ this.defaultValue = { hour: 0, minute: 0, second: 0 };
492
+ this.value = '';
493
+ this.formGroup = new FormGroup({
494
+ hour: new FormControl(this.defaultValue.hour, { nonNullable: true }),
495
+ minute: new FormControl(this.defaultValue.minute, { nonNullable: true }),
496
+ second: new FormControl(this.defaultValue.second, { nonNullable: true })
497
+ });
498
+ }
499
+ ngAfterViewInit() {
500
+ this.listenValueChanges();
501
+ }
502
+ listenValueChanges() {
503
+ this.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
504
+ if (this.onChange) {
505
+ const value = this.formGroup.getRawValue();
506
+ this.onChange({
507
+ hour: value.hour ?? this.defaultValue.hour,
508
+ minute: value.minute ?? this.defaultValue.minute,
509
+ second: value.second ?? this.defaultValue.second
510
+ });
511
+ }
512
+ });
513
+ }
514
+ writeValue(value) {
515
+ if (value) {
516
+ this.formGroup.setValue({
517
+ ...this.defaultValue,
518
+ ...value
519
+ }, { emitEvent: false });
520
+ }
521
+ else {
522
+ this.formGroup.reset(this.defaultValue, { emitEvent: false });
523
+ }
524
+ }
525
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTimePickerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
526
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilTimePickerComponent, selector: "ngil-time-picker", providers: [
527
+ {
528
+ provide: NG_VALUE_ACCESSOR,
529
+ useExisting: NgilTimePickerComponent,
530
+ multi: true
531
+ }
532
+ ], usesInheritance: true, ngImport: i0, template: "<form [formGroup]=\"formGroup\" class=\"ngil-time-picker\">\r\n <div class=\"ngil-time-picker__field\">\r\n <button #hourButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"hour\"\r\n [buttonUp]=\"hourButtonUp\"\r\n [buttonDown]=\"hourButtonDown\"\r\n [max]=\"23\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #hourButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n\r\n <span>:</span>\r\n\r\n <div class=\"ngil-time-picker__field\">\r\n <button #minuteButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"minute\"\r\n [buttonUp]=\"minuteButtonUp\"\r\n [buttonDown]=\"minuteButtonDown\"\r\n [max]=\"59\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #minuteButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n\r\n <span>:</span>\r\n\r\n <div class=\"ngil-time-picker__field\">\r\n <button #secondButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"second\"\r\n [buttonUp]=\"secondButtonUp\"\r\n [buttonDown]=\"secondButtonDown\"\r\n [max]=\"59\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #secondButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n</form>\r\n\r\n<ng-template #arrowUp>\r\n <svg\r\n _ngcontent-vre-c235=\"\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 0 100 100\"\r\n xml:space=\"preserve\"\r\n class=\"ngil-time-picker__arrow\"\r\n >\r\n <polyline\r\n _ngcontent-vre-c235=\"\"\r\n fill=\"none\"\r\n stroke=\"#000000\"\r\n stroke-width=\"10\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n points=\"10, 75 50, 25 90, 75\"\r\n ></polyline>\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #arrowDown>\r\n <svg\r\n _ngcontent-vre-c235=\"\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 0 100 100\"\r\n xml:space=\"preserve\"\r\n class=\"ngil-time-picker__arrow\"\r\n >\r\n <polyline\r\n _ngcontent-vre-c235=\"\"\r\n fill=\"none\"\r\n stroke=\"#000000\"\r\n stroke-width=\"10\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n points=\"10, 25 50, 75 90, 25\"\r\n ></polyline>\r\n </svg>\r\n</ng-template>\r\n", styles: [".ngil-time-picker{display:flex;align-items:center;background:#fff;border:1px solid #000;gap:.5rem;padding:.5rem}.ngil-time-picker__field{width:25px;position:relative;display:flex;flex-direction:column;align-items:center;gap:.5rem}.ngil-time-picker__input{width:calc(100% - 7px);padding:3px;text-align:center}.ngil-time-picker__button{background:none;border:none;position:relative;display:flex}.ngil-time-picker__arrow{width:18px;height:18px;cursor:pointer}\n"], dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i2.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i2.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "directive", type: NumberRotationDirective, selector: "input[ngilNumberRotation]", inputs: ["min", "max", "buttonUp", "buttonDown"] }] }); }
533
+ }
534
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTimePickerComponent, decorators: [{
535
+ type: Component,
536
+ args: [{ selector: 'ngil-time-picker', providers: [
537
+ {
538
+ provide: NG_VALUE_ACCESSOR,
539
+ useExisting: NgilTimePickerComponent,
540
+ multi: true
541
+ }
542
+ ], template: "<form [formGroup]=\"formGroup\" class=\"ngil-time-picker\">\r\n <div class=\"ngil-time-picker__field\">\r\n <button #hourButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"hour\"\r\n [buttonUp]=\"hourButtonUp\"\r\n [buttonDown]=\"hourButtonDown\"\r\n [max]=\"23\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #hourButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n\r\n <span>:</span>\r\n\r\n <div class=\"ngil-time-picker__field\">\r\n <button #minuteButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"minute\"\r\n [buttonUp]=\"minuteButtonUp\"\r\n [buttonDown]=\"minuteButtonDown\"\r\n [max]=\"59\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #minuteButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n\r\n <span>:</span>\r\n\r\n <div class=\"ngil-time-picker__field\">\r\n <button #secondButtonUp class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowUp\"></ng-container>\r\n </button>\r\n <input\r\n ngilNumberRotation\r\n class=\"ngil-time-picker__input\"\r\n formControlName=\"second\"\r\n [buttonUp]=\"secondButtonUp\"\r\n [buttonDown]=\"secondButtonDown\"\r\n [max]=\"59\"\r\n [min]=\"0\"\r\n (blur)=\"onBlur()\"\r\n />\r\n <button #secondButtonDown class=\"ngil-time-picker__button\">\r\n <ng-container *ngTemplateOutlet=\"arrowDown\"></ng-container>\r\n </button>\r\n </div>\r\n</form>\r\n\r\n<ng-template #arrowUp>\r\n <svg\r\n _ngcontent-vre-c235=\"\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 0 100 100\"\r\n xml:space=\"preserve\"\r\n class=\"ngil-time-picker__arrow\"\r\n >\r\n <polyline\r\n _ngcontent-vre-c235=\"\"\r\n fill=\"none\"\r\n stroke=\"#000000\"\r\n stroke-width=\"10\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n points=\"10, 75 50, 25 90, 75\"\r\n ></polyline>\r\n </svg>\r\n</ng-template>\r\n\r\n<ng-template #arrowDown>\r\n <svg\r\n _ngcontent-vre-c235=\"\"\r\n xmlns=\"http://www.w3.org/2000/svg\"\r\n xmlns:xlink=\"http://www.w3.org/1999/xlink\"\r\n viewBox=\"0 0 100 100\"\r\n xml:space=\"preserve\"\r\n class=\"ngil-time-picker__arrow\"\r\n >\r\n <polyline\r\n _ngcontent-vre-c235=\"\"\r\n fill=\"none\"\r\n stroke=\"#000000\"\r\n stroke-width=\"10\"\r\n stroke-linecap=\"round\"\r\n stroke-linejoin=\"round\"\r\n points=\"10, 25 50, 75 90, 25\"\r\n ></polyline>\r\n </svg>\r\n</ng-template>\r\n", styles: [".ngil-time-picker{display:flex;align-items:center;background:#fff;border:1px solid #000;gap:.5rem;padding:.5rem}.ngil-time-picker__field{width:25px;position:relative;display:flex;flex-direction:column;align-items:center;gap:.5rem}.ngil-time-picker__input{width:calc(100% - 7px);padding:3px;text-align:center}.ngil-time-picker__button{background:none;border:none;position:relative;display:flex}.ngil-time-picker__arrow{width:18px;height:18px;cursor:pointer}\n"] }]
543
+ }] });
544
+
545
+ class NgilTimePickerOverlayComponent {
546
+ constructor(overlay) {
547
+ this.overlay = overlay;
548
+ this.valueChanges$ = new Subject();
549
+ this.isOpen = false;
550
+ this.value = { hour: 0, minute: 0, second: 0 };
551
+ this.destroy$ = new Subject();
552
+ this.contentComponent = NgilTimePickerComponent;
553
+ }
554
+ ngOnDestroy() {
555
+ this.destroy$.next();
556
+ this.destroy$.complete();
557
+ }
558
+ open() {
559
+ this.overlayRef = this.overlay.create({
560
+ positionStrategy: this.getStrategy(),
561
+ hasBackdrop: true,
562
+ backdropClass: 'cdk-overlay-transparent-backdrop'
563
+ });
564
+ const portal = new ComponentPortal(this.contentComponent);
565
+ const componentRef = this.overlayRef.attach(portal);
566
+ this.componentInstance = componentRef.instance;
567
+ this.componentInstance.writeValue(this.value);
568
+ this.componentInstance.formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(() => {
569
+ const value = this.componentInstance?.formGroup.getRawValue();
570
+ this.valueChanges$.next({
571
+ hour: value?.hour ?? 0,
572
+ minute: value?.minute ?? 0,
573
+ second: value?.second ?? 0
574
+ });
575
+ });
576
+ this.overlayRef
577
+ .backdropClick()
578
+ .pipe(takeUntil(this.destroy$))
579
+ .subscribe(() => {
580
+ this.close();
581
+ });
582
+ this.isOpen = true;
583
+ }
584
+ close() {
585
+ this.destroyOverlay();
586
+ }
587
+ destroyOverlay() {
588
+ this.destroy$.next();
589
+ this.componentInstance?.ngOnDestroy();
590
+ this.overlayRef?.dispose();
591
+ this.componentInstance = undefined;
592
+ this.overlayRef = undefined;
593
+ this.isOpen = false;
594
+ }
595
+ setValue(value) {
596
+ this.value = value;
597
+ if (this.componentInstance) {
598
+ this.componentInstance.writeValue(this.value);
599
+ }
600
+ }
601
+ getStrategy() {
602
+ const primaryX = 'start';
603
+ const secondaryX = primaryX === 'start' ? 'end' : 'start';
604
+ const primaryY = 'top';
605
+ const secondaryY = 'bottom';
606
+ if (!this.origin) {
607
+ return undefined;
608
+ }
609
+ const strategy = this.overlay
610
+ .position()
611
+ .flexibleConnectedTo(this.origin)
612
+ .withPositions([
613
+ {
614
+ originX: primaryX,
615
+ originY: secondaryY,
616
+ overlayX: primaryX,
617
+ overlayY: primaryY
618
+ },
619
+ {
620
+ originX: primaryX,
621
+ originY: primaryY,
622
+ overlayX: primaryX,
623
+ overlayY: secondaryY
624
+ },
625
+ {
626
+ originX: secondaryX,
627
+ originY: secondaryY,
628
+ overlayX: secondaryX,
629
+ overlayY: primaryY
630
+ },
631
+ {
632
+ originX: secondaryX,
633
+ originY: primaryY,
634
+ overlayX: secondaryX,
635
+ overlayY: secondaryY
636
+ }
637
+ ]);
638
+ return strategy;
639
+ }
640
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTimePickerOverlayComponent, deps: [{ token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
641
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.2", type: NgilTimePickerOverlayComponent, selector: "ngil-time-picker-overlay", ngImport: i0, template: '', isInline: true }); }
642
+ }
643
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilTimePickerOverlayComponent, decorators: [{
644
+ type: Component,
645
+ args: [{
646
+ selector: 'ngil-time-picker-overlay',
647
+ template: ''
648
+ }]
649
+ }], ctorParameters: () => [{ type: i1$1.Overlay }] });
650
+
651
+ class TimePickerDirective {
652
+ constructor(elementRef, inputComponent, ngControl) {
653
+ this.elementRef = elementRef;
654
+ this.inputComponent = inputComponent;
655
+ this.ngControl = ngControl;
656
+ this.changed = new EventEmitter();
657
+ this.destroy$ = new Subject();
658
+ this.onKeyDown = (event) => {
659
+ if (isNaN(+event.key) && event.key !== ':' && event.key.length === 1) {
660
+ event.preventDefault();
661
+ }
662
+ };
663
+ this.onInput = (event) => {
664
+ const value = this.getTimePickerValue(event.target.value);
665
+ this.picker?.setValue({
666
+ hour: +value.hour,
667
+ minute: +value.minute || 0,
668
+ second: +value.second || 0
669
+ });
670
+ };
671
+ }
672
+ ngOnInit() {
673
+ this.ngControl?.control?.setValidators([this.timeValidator()]);
674
+ }
675
+ timeValidator() {
676
+ return (control) => {
677
+ const value = this.getTimePickerValue(control.value);
678
+ if (this.itemHasError(value.hour, 23)) {
679
+ return {
680
+ invalidHour: true
681
+ };
682
+ }
683
+ if (this.itemHasError(value.minute, 59)) {
684
+ return {
685
+ invalidMinute: true
686
+ };
687
+ }
688
+ if (this.itemHasError(value.second, 59)) {
689
+ return {
690
+ invalidSecond: true
691
+ };
692
+ }
693
+ return null;
694
+ };
695
+ }
696
+ itemHasError(value, max, min = 0) {
697
+ if (value && (value.length > 2 || +value > max || +value < min)) {
698
+ return true;
699
+ }
700
+ return false;
701
+ }
702
+ getTimePickerValue(value) {
703
+ const split = value?.split(':');
704
+ return {
705
+ hour: split ? split[0] : '00',
706
+ minute: split ? split[1] : '00',
707
+ second: split ? split[2] : '00'
708
+ };
709
+ }
710
+ ngAfterViewInit() {
711
+ if (this.picker) {
712
+ this.picker.origin = this.elementRef;
713
+ this.picker.valueChanges$.pipe(takeUntil(this.destroy$)).subscribe(value => {
714
+ this.setInputText(value);
715
+ this.changed.emit(value);
716
+ });
717
+ }
718
+ }
719
+ setInputText(value) {
720
+ const text = [this.getItemText(value.hour), this.getItemText(value.minute), this.getItemText(value.second)].join(':');
721
+ this.inputComponent?.control.setValue(text);
722
+ this.elementRef.nativeElement.value = text;
723
+ this.ngControl?.control?.setValue(text);
724
+ }
725
+ getItemText(value) {
726
+ return value.toString().padStart(2, '0');
727
+ }
728
+ ngOnDestroy() {
729
+ this.destroy$.next();
730
+ this.destroy$.complete();
731
+ }
732
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: TimePickerDirective, deps: [{ token: i0.ElementRef }, { token: NgilInputComponent, optional: true }, { token: i2.NgControl, optional: true }], target: i0.ɵɵFactoryTarget.Directive }); }
733
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.3.2", type: TimePickerDirective, selector: "[ngilTimePicker]", inputs: { picker: "picker" }, outputs: { changed: "changed" }, host: { listeners: { "keydown": "onKeyDown($event)", "input": "onInput($event)" } }, ngImport: i0 }); }
734
+ }
735
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: TimePickerDirective, decorators: [{
736
+ type: Directive,
737
+ args: [{
738
+ selector: '[ngilTimePicker]'
739
+ }]
740
+ }], ctorParameters: () => [{ type: i0.ElementRef }, { type: NgilInputComponent, decorators: [{
741
+ type: Optional
742
+ }] }, { type: i2.NgControl, decorators: [{
743
+ type: Optional
744
+ }] }], propDecorators: { picker: [{
745
+ type: Input
746
+ }], changed: [{
747
+ type: Output
748
+ }], onKeyDown: [{
749
+ type: HostListener,
750
+ args: ['keydown', ['$event']]
751
+ }], onInput: [{
752
+ type: HostListener,
753
+ args: ['input', ['$event']]
754
+ }] } });
755
+
756
+ class NgilUiFormModule {
757
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilUiFormModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
758
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "17.3.2", ngImport: i0, type: NgilUiFormModule, declarations: [NgilInputComponent,
759
+ NgilTimePickerComponent,
760
+ NgilTimePickerOverlayComponent,
761
+ PickerToggleComponent,
762
+ NumberRotationDirective,
763
+ TimePickerDirective,
764
+ NgilSelectComponent,
765
+ NgilTextareaComponent,
766
+ NgilSelectOptionsComponent,
767
+ NgilOverlayComponent,
768
+ OverlayToggleDirective], imports: [CommonModule, ReactiveFormsModule, OverlayModule], exports: [NgilInputComponent,
769
+ NgilSelectComponent,
770
+ NgilTextareaComponent,
771
+ NgilTimePickerComponent,
772
+ NgilTimePickerOverlayComponent,
773
+ PickerToggleComponent,
774
+ NumberRotationDirective,
775
+ TimePickerDirective] }); }
776
+ static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilUiFormModule, imports: [CommonModule, ReactiveFormsModule, OverlayModule] }); }
777
+ }
778
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.2", ngImport: i0, type: NgilUiFormModule, decorators: [{
779
+ type: NgModule,
780
+ args: [{
781
+ imports: [CommonModule, ReactiveFormsModule, OverlayModule],
782
+ declarations: [
783
+ NgilInputComponent,
784
+ NgilTimePickerComponent,
785
+ NgilTimePickerOverlayComponent,
786
+ PickerToggleComponent,
787
+ NumberRotationDirective,
788
+ TimePickerDirective,
789
+ NgilSelectComponent,
790
+ NgilTextareaComponent,
791
+ NgilSelectOptionsComponent,
792
+ NgilOverlayComponent,
793
+ OverlayToggleDirective
794
+ ],
795
+ exports: [
796
+ NgilInputComponent,
797
+ NgilSelectComponent,
798
+ NgilTextareaComponent,
799
+ NgilTimePickerComponent,
800
+ NgilTimePickerOverlayComponent,
801
+ PickerToggleComponent,
802
+ NumberRotationDirective,
803
+ TimePickerDirective
804
+ ]
805
+ }]
806
+ }] });
807
+
808
+ /**
809
+ * Generated bundle index. Do not edit.
810
+ */
811
+
812
+ export { NgilInputComponent, NgilSelectComponent, NgilTextareaComponent, NgilTimePickerComponent, NgilTimePickerOverlayComponent, NgilUiFormModule, NumberRotationDirective, PickerToggleComponent, TimePickerDirective };
813
+ //# sourceMappingURL=ngil-form-inputs.mjs.map